Building OpenSSH for OS X?
How do I build OpenSSH using the updated OpenSSL on OS X? Where do I find the instructions?
Grawity was correct - I downloaded the wrong OpenSSH. I needed a portable one, and not the one provided at the FTP link. The portable ones are listed at the bottom of Portable OpenSSH.
Once you have the portable one, unpack, and then perform the following. The following assumes you have an updated OpenSSL libcrypto
installed at /usr/local/ssl/darwin
and an updated Zlib libz
at /usr/local
. Adjust them to suite your taste.
Replace -lz with absolute path to archive
This is needed to ensure static linking because there is no apparent option for it in configure
. When the binary is built, otool -L
will show there are no external Zlib dependencies.
$ grep "\-lz" *
configure:{ echo "$as_me:$LINENO: checking for deflate in -lz" >&5
configure:echo $ECHO_N "checking for deflate in -lz... $ECHO_C" >&6; }
configure:LIBS="-lz $LIBS"
configure: LIBS="-lz $LIBS"
configure: LIBS="$LIBS -lz"
configure.ac: LIBS="$LIBS -lz"
Then:
$ sed -i "" 's|-lz|/usr/local/lib/libz.a|g' config.h.in configure configure.ac
$
Replace -lcrypto with absolute path to archive
This is needed to ensure static linking because there is no apparent option for it in configure
. When the binary is built, otool -L
will show there are no external OpenSSL dependencies.
$ grep "\-lcrypto" *
configure: LIBS="-lcrypto $LIBS"
configure.ac: LIBS="-lcrypto $LIBS"
Then:
$ sed -i "" 's|-lcrypto|/usr/local/ssl/darwin/lib/libcrypto.a|g' configure configure.ac
$
In the above, I use /usr/local/ssl/darwin
as --openssldir
when building the OpenSSL library. Its usually just /usr/local/ssl
. Adjust it as necessary.
Configure OpenSSH
Configure OpenSSH with the needed paths. You might need to include a OS X library, too.
If find /usr/lib/ -name libsandbox*
returns libsandbox.dylib
, then you need to include --with-libs="-lsandbox
. Its missing on OS X 10.5, but its present on OS X 10.8. If the library is present but --with-libs
is omitted, then it will result in an error similar to riemann.local sshd[15748]: fatal: ssh_sandbox_child: sandbox_init: dlopen(/usr/lib/libsandbox.1.dylib, 261): image not found [preauth]
.
$ ./configure --without-ssh1 --with-ssl-dir=/usr/local/ssl/darwin --with-zlib=/usr/local \
--with-libs="-lsandbox" --prefix=/usr/local
checking for gcc... gcc
checking for C compiler default output file name... a.out
...
OpenSSH has been configured with the following options:
User binaries: /usr/local/bin
System binaries: /usr/local/sbin
Configuration files: /usr/local/etc
...
Host: x86_64-apple-darwin12.6.0
Compiler: gcc
Compiler flags: -g -O2 -Qunused-arguments -Wunknown-warning-option -Wall -Wpointer-arith
-Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess
-Wno-pointer-sign -Wno-unused-result -fno-strict-aliasing -D_FORTIFY_SOURCE=2
-ftrapv -fno-builtin-memset -fstack-protector-all -fPIE
Preprocessor flags: -I/usr/local/ssl/darwin/include -I/usr/local/include
Linker flags: -L/usr/local/ssl/darwin/lib -L/usr/local/lib -fstack-protector-all -pie
Libraries: /usr/local/ssl/darwin/lib/libcrypto.a /usr/local/lib/libz.a -lsandbox -lresolv
You might need --with-pam
to get password authentication working. I was not concerned with the feature, so I did not add the configuration option.
Build and Install OpenSSH
The -fwrapv
is somewhat troubling when seen in high integrity software. That usually means there's an illegal C program with undefined behavior afoot. The developers have not fixed it, so they use -fwrapv
as a band-aide.
$ make
conffile=`echo sshd_config.out | sed 's/.out$//'`; \
...
gcc -g -O2 -Qunused-arguments -Wunknown-warning-option -Wall -Wpointer-arith -Wuninitialized
-Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign
-Wno-unused-result -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset
-fstack-protector-all -fPIE -I. -I.. -I. -I./.. -I/usr/local/ssl/darwin/include
-I/usr/local/include -DHAVE_CONFIG_H -c arc4random.c
gcc -g -O2 -Qunused-arguments -Wunknown-warning-option -Wall -Wpointer-arith -Wuninitialized
-Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign
-Wno-unused-result -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset
-fstack-protector-all -fPIE -I. -I.. -I. -I./.. -I/usr/local/ssl/darwin/include
-I/usr/local/include -DHAVE_CONFIG_H -c bsd-asprintf.c
...
External dependencies (or lack thereof) can be verified with:
$ otool -L ./sshd
./sshd:
/usr/lib/libsandbox.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
Unfortunately, there is no make check
or make test
targets, so there's no apparent way to test the software before installing it.
$ sudo make install
...
Generating public/private ed25519 key pair.
Your identification has been saved in /usr/local/etc/ssh_host_ed25519_key.
Your public key has been saved in /usr/local/etc/ssh_host_ed25519_key.pub.
The key fingerprint is:
SHA256:u/xQ6haFqxjG0fBgSMt0W58N8zmhu+NmyQxNMkMcwPc [email protected]
The key's randomart image is:
+--[ED25519 256]--+
| .ooooo.o . |
| o.o=o+. B o |
| o..B .+.= |
| . * E... |
| . . *So. |
| + . += |
| . o =*o |
| . .+B+ |
| +=.. |
+----[SHA256]-----+
...
Create a Plist for the new SSH binary
The following uses the existing ssh.plist
, removes the Apple wrapper script, and changes the port number. Copy it to /System/Library/LaunchDaemons/ssh-7.1.plist
.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<true/>
<key>Label</key>
<string>com.openssh.sshd.7-1</string>
<key>Program</key>
<string>/usr/local/sbin/sshd</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/sbin/sshd</string>
<string>-i</string>
<string>-e</string>
<string>-f</string>
<string>/usr/local/etc/sshd_config</string>
<string>-o</string>
<string>PidFile=/var/run/sshd-7.1.pid</string>
</array>
<key>Sockets</key>
<dict>
<key>Listeners</key>
<dict>
<key>SockServiceName</key>
<string>1522</string>
</dict>
</dict>
<key>inetdCompatibility</key>
<dict>
<key>Wait</key>
<false/>
</dict>
<key>StandardErrorPath</key>
<string>/var/log/sshd-7.1.log</string>
<key>SHAuthorizationRight</key>
<string>system.preferences</string>
</dict>
</plist>
There's a few things going on in the plist:
- the service label was changed to
com.openssh.sshd.7-1
to avoid colliding with Apple'scom.openssh.sshd
- the PID file was changed to
var/run/sshd-7.1.pid
to avoid colliding with Apple'svar/run/sshd.pid
- the program's absolute path was included in
ProgramArguments
due to asshd re-exec requires execution with an absolute path
while servicing client connections -
sshd_config
is called out specifically to avoid open questions and confusion. But its used by default - the use of the -
i
option even though its aninetd(8)
option. According to sshd and -i option on OS X, it should be used
Start the new SSH service
Use launchd to start the service. Notice the use of -w
to avoid the "nothing found to load" error message because the service is disabled.
$ sudo launchctl load -w /System/Library/LaunchDaemons/ssh-7.1.plist
Finally, verify the new SSH server is operating:
$ netstat -an | grep 1522
tcp6 0 0 *.1522 *.* LISTEN
tcp4 0 0 *.1522 *.* LISTEN
I visited openssh.com and fetched the latest version (7.1) via FTP.
The link under "For OpenBSD: FTP / HTTP" is, as the name says, for OpenBSD only. It needs to be built using the OpenBSD 'Ports' tools.
Since you're running OS X, not OpenBSD, you'll have to download it from "For other OSs → Others…". (Scroll down to the "Download" section.) The official OpenSSH-portable 7.1p1 tarball definitely has both a configure
script and an INSTALL
document.
Static linking shouldn't be necessary; OS X binaries can depend on libraries at an absolute path. (I think that might even be the default?)
There is no download link on the homepage; you kinda have to rummage for it.
I agree that the website is sort of stuck in 1990's, but I wouldn't say two clicks instead of one count as rummaging... If it had a download page, it would just contain the same OS links which are already in the sidebar, wouldn't it?
Where do I find the instructions?
Take a look at Homebrew, especially its openssh formula. Also:
- http://www.dctrwatson.com/2013/07/how-to-update-openssh-on-mac-os-x/
- https://mochtu.de/2015/01/07/updating-openssh-on-mac-os-x-10-10-yosemite/