Many system administrators need to restrict file transfers via SCP/SFTP while maintaining regular SSH shell access for users. This security requirement often arises in regulated environments where data exfiltration needs monitoring.
The most effective approach modifies the SSH server configuration to disable the SCP subsystem:
# /etc/ssh/sshd_config Subsystem sftp /usr/lib/openssh/sftp-server # Comment this out #Subsystem scp /usr/libexec/openssh/scp # Explicitly disable if exists
This prevents scp from initiating transfers while preserving normal shell access. After modifying, restart sshd:
sudo systemctl restart sshd # systemd systems sudo svcadm restart ssh # Solaris SMF
For finer control, create a wrapper script that filters scp commands:
#!/bin/bash
# /usr/local/bin/scp_wrapper
if [[ "$SSH_ORIGINAL_COMMAND" =~ scp ]]; then
logger -p authpriv.warn "SCP attempt blocked: $SSH_ORIGINAL_COMMAND"
echo "SCP file transfers are disabled on this system" >&2
exit 1
fi
exec $SHELL
Then configure sshd to use this wrapper:
Match Group restricted_users
ForceCommand /usr/local/bin/scp_wrapper
To monitor scp attempts even when blocking them, implement rsyslog filtering:
# /etc/rsyslog.d/30-scpmon.conf
if $programname == 'sshd' and ($msg contains 'scp' or $msg contains 'sftp') then {
action(type="omfile" file="/var/log/scp_attempts.log")
stop
}
Sample log entry format:
Aug 15 10:23:45 server1 sshd[12345]: scp attempt by user1 from 192.168.1.100: scp -r /data
After implementation, verify with:
# Should fail with "command not found" or custom error scp testfile user@server:/tmp # Should succeed normally ssh user@server "ls -l"
- This doesn't prevent users from piping files through ssh commands
- Some legacy systems may require patching for proper scp subsystem removal
- Consider implementing additional controls like two-factor authentication
SCP (Secure Copy Protocol) and SSH share the same underlying transport mechanism, which makes selectively disabling SCP while preserving SSH shell access a non-trivial task. OpenSSH implements SCP as a subsystem that gets invoked through the SSH protocol itself.
The most straightforward approach is to modify the sshd_config file. Add or modify these directives:
# /etc/ssh/sshd_config
Match Group !admins
ForceCommand /bin/bash
DenyUsers * scp
Subsystem sftp internal-sftp -l INFO -f AUTH
This configuration:
- Forces regular users into an interactive shell
- Explicitly denies SCP access
- Restricts SFTP subsystem usage
Create a custom shell wrapper that intercepts SCP commands:
#!/bin/bash
# /usr/local/bin/restricted_shell.sh
case $SSH_ORIGINAL_COMMAND in
scp*)
echo "SCP access prohibited" >&2
exit 1
;;
*)
exec $SHELL -c "$SSH_ORIGINAL_COMMAND"
;;
esac
Then modify sshd_config:
ForceCommand /usr/local/bin/restricted_shell.sh
For comprehensive SCP logging, combine these approaches:
# Enhanced logging in sshd_config
LogLevel VERBOSE
Subsystem scp /usr/libexec/openssh/sftp-server -l INFO -f AUTH
# Custom syslog configuration
if $programname == 'sshd' and $msg contains 'scp' then {
action(type="omfile" file="/var/log/scp_audit.log")
stop
}
For maximum isolation, implement chroot jails:
Match User restricted_user
ChrootDirectory /chroot/restricted
X11Forwarding no
AllowTcpForwarding no
PermitTTY yes
ForceCommand internal-sftp
Verify your settings with these commands:
# Test SSH access ssh -v user@host # Test SCP rejection scp -v testfile user@host:/tmp # Check logs tail -f /var/log/auth.log | grep scp
- These methods won't prevent
ssh user@host "cat file" > localfiletransfers - Consider using SELinux/AppArmor for additional protection
- Regularly audit your sshd logs for bypass attempts