=============================================================================== Server side SSHD =============================================================================== Debugging SSHD - why is it failing! You can get a verbose output of what a client does, but it is harder to find out why a sshd server is failing. Run a personal sshd verbosely on a specific port in one window while you ssh to that server in another window. Note: you will need to open the firewall too # Open a firewall port temporarily firewall-cmd --list-all # current zone definition firewall-cmd --zone=public --add-port=2222/tcp # start a daemon on the server (system settings) /sbin/sshd -d -p 2222 NOTE: You can tell SSHD to ignore the system configs You will need to your own host keys if you are not root! ssh-keygen -f ~/.ssh/ssh_host_ecdsa_key -t ecdsa -P '' /sbin/sshd -p 2222 -f /dev/null -h ~/.ssh/ssh_host_ecdsa_key \ ...other options... # On client (separate window) ssh -v -p 2222 user@server # check the output from your sshd command # kill the sshd that you ran pkill -u "$USER" sshd # Cleanup firewall-cmd --zone=public --remove-port=2222/tcp firewall-cmd --list-all ------------------------------------------------------------------------------- Restrict User access.... Basic =======8<-------- DenyUsers bob,joe,phil =======8<-------- Alternative to DenyUsers =======8<-------- Match User bob,joe,phil PasswordAuthentication yes AllowTCPForwarding yes ForceCommand /bin/echo 'We talked about this guys. No SSH for you!' Match All =======8<-------- Only allow 'control' users from specific IP subnet =======8<-------- Match User ansible,backup,support Address *,!176.x.x.x DenyUsers ansible,backup,support Match User backup AllowTcpForwarding yes AllowAgentForwarding yes PermitListen 127.0.0.1:2223 Match All =======8<-------- ------------------------------------------------------------------------------- Password Auth... This FAILS to allow password authentication =======8<-------- PasswordAuthentication no Match User anthony PasswordAuthentication yes Match All =======8<-------- =======8<-------- Match User anthony PasswordAuthentication yes Match All PasswordAuthentication no =======8<-------- ------------------------------------------------------------------------------- Ssh Server, Limit what commands will work... User level... In the ".ssh/authorized_keys" file you can define a key as command="/path/to/some/command args..." ssh-dss ... Or the sshd "ForceCommand" can be used to override this. Ensure it remains all on one line. This will force ssh to only execute the command that was given, and NOT the command actually requested by the client. The command is passed as a -c '...' argument to the users login shell. Example commands... /usr/bin/cvs server only allow cvs upload/download /usr/bin/ssh user@host always forward user to another host The 'command' can be a special script that looks at the user requested command, and then determines the appropriate course of action. The original command is saved by SSH into the environment variable SSH_ORIGINAL_COMMAND. This single argument would normally be given to users login sheel as a '-c ...' option. For example, see my "ssh_restricted" script that restricts commands to specific directory of pre-defined commands. NOTE: As with any SSH remote command, the SSH_ORIGINAL_COMMAND will have lost all the original quoting and escaping of the command and arguments. It will be typically re-interpreted by the user's login shell before execution. It is thus a good idea to parse the command to it does what you would allow the user to do. Examples of use. * Limit remote commands to specific ones * Parse rsync requests for funny shell escapes, and/or source requests * Log what commands are being requested for remote execution. ------------------------------------------------------------------------------- Limited remote commands... For example see the script 'restricted_ssh' script In ~/.ssh/authorisedkeys add restrict,command="/path/to/restricted_ssh" ssh-dss ... Make sure it remains all on one line. Only accounts identified by that public key will be resctricted. Edit script as appropriate for logging. Create "ssh_scripts" sub-directory and add links or scripts the remote user is allowed to run... For example... ln -s /bin/date ssh_scripts ln -s /bin/hostname ssh_scripts Ensure that scripts do not provide access to a shell, and require no arguments Note 'ls' is a built-in command, provided by the "restricted_ssh" script. Test from remote users account... ssh server FAIL no login shell allowed ssh server ls List scripts available ssh server date return date on secure server ssh server hostname return hostname of secure server ssh server date +%F FAIL arguments not allowed ssh server ps FAIL no such script ssh server /bin/ps FAIL path characters used ssh server 'date;ps' FAIL illegal charcater (only alphanum) ------------------------------------------------------------------------------- Limit ssh to sftp logins only Add the following (with appropriate group) to "sshd_config" and restart the service. AllowTcpForwarding no Subsystem sftp internal-sftp #/usr/lib/openssh/sftp-server ForceCommand internal-sftp Match group {your_group-here} ChrootDirectory /home/%u ------------------------------------------------------------------------------- SSH and X Windows For X Windows to work you need these in sshd_config X11Forwarding yes AddressFamily inet That last is to disable IPv6 from messing with X forwarding You can also add "OPTIONS=-4" to "/etc/sysconfig/sshd" instead ------------------------------------------------------------------------------- SSH security notes and ideas. Turn off port forward on machines with multi-users See http://www.semicomplete.com/articles/ssh-security/ Basically because of -N ssh does not need a working shell to use port forwarding, and thus using a shell like /bin/false will not disable a user from using a port forward. If port forwarding is needed, then consider including a valid 'shell test' in the PAM login system. That probably should be added in any case. Use a white list of acceptable IP's The problem is that you can't login from a random terminal when you need to. You may also have too many users to control access in this way. Only allow public key access. <-- *** No passwords allowed, period. For random remote logins have putty and your private ssh key on a USB stick. NB: using the private key on public machines may not be a very good idea. Spot and deny SSH dictionary attacks... "denyHosts"... Adds 'deny' lines to the '/etc/hosts.deny" file when it sees an attacks in the /var/log/secure file. A script to do the same thing locally is simple too, so you can DIY it. "sshdfilter", runs sshd with a -e filter to add iptable denys in real time rather than after the fact, often before a password has even been requested. It is highly configurable, and removed old entries according to various rules. However it is not avaialble as a yum package (yet) http://www.csc.liv.ac.uk/~greg/sshdfilter/ "sshd_sentry" (may not be released), after five failed attempts the IP address is blocked for 24 hours. The problem is it leaves you vulnerable to a DoS attack from competitors, It does not just block SSH ports but also denies web bot access for google and yahoo search engines too. "failban" watched logs and network denys access temporarilly. Limit logins to specific usernames. Dictionary attackers will give up as they don't really know your allowed user list. Change the sshd port on the external router... EG port forward 7xxx on the router to 22 on your internal machine Note do not use port 2222. Everyone uses that and script kiddies will catch on to this, and scan for that port too. Not at time of writing though. One Time, or limited time Passwords. Do you have an SMS-enabled cell phone? For an operating systems class project this spring I wrote a simple PAM module what would look up the user's cell phone number then send an eight-digit random number to the user's cell phone, which the user has to type in at the login prompt. I used this module to secure the outward-facing sshd (on port 7xxx), blocking port 22 at the firewall so I could continue to ssh around my home network without spending $0.15 every time I rebooted my laptop. As long as your phone has a signal, you have effective token-based authentication. -------------------------------------------------------------------------------