{"id":14,"date":"2009-08-28T19:21:22","date_gmt":"2009-08-28T19:21:22","guid":{"rendered":"http:\/\/www.vidarholen.net\/contents\/blog\/?p=14"},"modified":"2009-08-28T19:22:32","modified_gmt":"2009-08-28T19:22:32","slug":"using-ssh-keys-from-untrusted-clients","status":"publish","type":"post","link":"https:\/\/www.vidarholen.net\/contents\/blog\/?p=14","title":{"rendered":"Using SSH keys from untrusted clients"},"content":{"rendered":"<p>We all know and love OpenSSH&#8217;s scriptability. For example:<\/p>\n<pre>\r\n# Burn file.iso from 'host' locally without using disk space\r\nssh host cat file.iso | cdrecord driveropts=burnfree speed=4 - \r\n\r\n# Create a uptime high score list \r\nfor host in hostone hosttwo hostthree hostfour\r\ndo \r\n    echo \"$(ssh -o BatchMode=yes $host \"cut -d\\  -f 1 \/proc\/uptime\" \\\r\n                 || echo \"0 host is unavailable: \") $host\"\r\ndone | sort -rn \r\n<\/pre>\n<p>The former is something you&#8217;d just do from your own box, since you need to be physically present to insert the CD anyways. But what if you want to automate the latter&mdash;commands that repetedly poll or invoke something&mdash;from a potentially untrustworthy box? <\/p>\n<p>Preferably, you&#8217;d use something other than ssh. Perhaps an entry in inetd that invokes the app, or maybe a cgi script (potentially over SSL and with password protection). But let&#8217;s say that for whichever reason (firewalls, available utilities, application interfaces) that you do want to use ssh. <\/p>\n<p>In those cases, you won&#8217;t be there to type in a password or unlock your ssh keys, and you don&#8217;t want someone to just copy the passwordless key and run their own commands.<\/p>\n<p>OpenSSH has a lot of nice features, and some of them relate to limiting what a user can do with a key. If you generate a passwordless key pair with ssh-keygen, you can add the following to .ssh\/authorized_keys:<\/p>\n<pre>\r\ncommand=\"uptime\" ssh-rsa AAAASsd+olg4(rest of public key follows)\r\n<\/pre>\n<p>Select the key to use with <code>ssh -i key ...<\/code>. This will make sure that anyone authenticated with this key pair will only be able to run &#8220;uptime&#8221; and not any other commands (including scp\/sftp). This seems clever enough, but we&#8217;re not entirely out of the woods yet. SSH supports more than running commands.<\/p>\n<p>Someone might use your key to forward spam via local port forwarding, or they could open a bunch of ports on your remote host and spoof services with remote port forwarding. <\/p>\n<p>Some less well documented authorized_keys options will help:<\/p>\n<pre>\r\n#This is really just one line: \r\ncommand=\"uptime\",   \r\nfrom=\"192.168.1.*\",\r\nno-port-forwarding,\r\nno-x11-forwarding,\r\nno-pty ssh-rsa AAAASsd+olg4(rest of public key follows)\r\n<\/pre>\n<p>Now we&#8217;ve disabled port forwarding including socks, x11 forwarding (shouldn&#8217;t matter, but hey), PTY allocation (due to DoS). And for laughs, we&#8217;ve limited the allowed clients to a subnet of IPs. <\/p>\n<p>Clients can still hammer the service, and depending on the command, that could cause DoS. However, we&#8217;ve drastically reduced the risks of handing out copies of the key. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>We all know and love OpenSSH&#8217;s scriptability. For example: # Burn file.iso from &#8216;host&#8217; locally without using disk space ssh host cat file.iso | cdrecord driveropts=burnfree speed=4 &#8211; # Create a uptime high score list for host in hostone hosttwo hostthree hostfour do echo &#8220;$(ssh -o BatchMode=yes $host &#8220;cut -d\\ -f 1 \/proc\/uptime&#8221; \\ || &hellip; <a href=\"https:\/\/www.vidarholen.net\/contents\/blog\/?p=14\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Using SSH keys from untrusted clients&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[5,4,22],"tags":[],"class_list":["post-14","post","type-post","status-publish","format-standard","hentry","category-advanced-linux","category-linux","category-security"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=\/wp\/v2\/posts\/14","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=14"}],"version-history":[{"count":0,"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=\/wp\/v2\/posts\/14\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=14"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=14"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=14"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}