Create usual user on destination server. Make sure it have no password and no expiration set (hint: look into /etc/shadow). This disable remote login using password authentication schema. Check that root can do "su" to it.
Prepare authorized_keys makes magic:
# su - sshruser $ mkdir -m700 .ssh $ cat > .ssh/authorized_keys << EOF # # This user is restricted to run some commands only. # using "command" parameter mandatory. This also disallow sftp/scp. # command="/usr/local/bin/0000 $SSH_ORIGINAL_COMMAND" ssh-rsa AAAAB3NzaC1yc2EAAAAB wAAAIEA14L/6GyIiK1AeOiyPTkYmZvl1q4aSvuiA7Wsn7oKL8AUQsiaov8Xu6oVx6WOr1Zsp9Ii3C+ry J4BZY87++tUgkQFvpf3FiXHFV+q2dYTdIocYC4+MdZYRNgwG+hyzsSN61pZ08PgTPJIVJGqO2Z22xE2Z elGO+fQfmn0TCJSE= remoteuser@remoteserver EOF $
As you see, the SSH public key prepended with command directive. Lets prepare /usr/local/bin/0000 script:
# cat > /usr/local/bin/0000 << EOF #!/bin/sh # Log full command echo "$0" "$@" | logger -t remssh # Strip previous "sudo -u appuser" : while [ 'x'"$1" != "xALLOWED-COMMAND" ] ; do shift || break done [ 'x'"$1" = 'x' ] && { echo "Not allowed command" ; exit 1 ; } # Additional security level sat by sudo: sudo -u appuser $(echo $@ | sed -e 's/"//g' ) EOF # chmod +x /usr/local/bin/0000
Not suprise, that ALLOWED-COMMAND works; let's see other tries:
$ ssh sshruser@sshserver id Not allowed command $ sftp sshruser@sshserver Connecting to sshserver... Received message too long 1315927072 $ scp /bin/bash sshruser@sshserver:/tmp/ Not allowed command
Clone SSH service that will use another, its own sshd_config. Example of mine:
# egrep -v "^$|^#" /etc/ssh/sshd_sftp_config Port 1234 PermitRootLogin no AuthorizedKeysFile .ssh/authorized_keys PasswordAuthentication no UsePAM yes AllowAgentForwarding no AllowTcpForwarding no X11Forwarding no UsePrivilegeSeparation sandbox # Default for new installations. ChrootDirectory /srv/www/https/%u Subsystem sftp internal-sftp ForceCommand internal-sftp -u 002
Create user without password and without login shell:
# SFTPUSER=mysftpuser # useradd -c "SFTP user" -m -s /bin/false $SFTPUSER # eval H=~$SFTPUSER # mkdir -v -m700 $H/.ssh # cat > $H/.ssh/authorized_keys PASTE HERE USER'S PUBLIC SSH KEY. GENERATE NEW ONE SOMEWHERE, IF USER DOES NOT HAVE IT - see next commands. Press Ctrl-D after pasted. #####Example to generate SSH key somewhere on linux: ## ssh-keygen -b 2048 -C $SFTPUSER@$(hostname -f) -f /tmp/$SFTPUSER@$(hostname -f) ## cp /tmp/$SFTPUSER@$(hostname -f) $H/.ssh/authorized_keys #####Send private key /tmp/$SFTPUSER@$(hostname -f) to user. # chown -R $SFTPUSER $H
Paste SSH public key into his .ssh/authorized_keys file and care about ownership and permissions.
Create directory structure to keep uploaded files:
# mkdir /srv/www/https/$SFTPUSER # mkdir /srv/www/https/$SFTPUSER/uploads # chown $SFTPUSER /srv/www/https/$SFTPUSER/uploadsChecking:
$ ssh -p 1234 sftp-server X11 forwarding request failed on channel 0 This service allows sftp connections only. Connection to sftp-server closed. $ scp -P 1234 sftp-server:/etc/passwd /tmp/ protocol error: mtime.sec not present $ scp -P 1234 /etc/passwd sftp-server:/tmp/ This service allows sftp connections only. $ sftp -P 1234 sftp-server Connected to sftp-server. sftp> pwd Remote working directory: / sftp> ls uploads sftp> bye
Let's assume that your environment is controlled by Ansible tower, and you want to protect such a powerful SSH key with additional options.
The man 8 sshd describes format of .ssh/authorized_keys and names available options. Here is an example of additional restrictions that may be useful for such a control station:
from="10.0.0.*,!host1,*.co.uk",restrict,pty ssh-rsa AAAAB3NzaC1...