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" > localfile
transfers - Consider using SELinux/AppArmor for additional protection
- Regularly audit your sshd logs for bypass attempts