-
-
Save fumiyas/b4aaee83e113e061d1ee8ab95b35608b to your computer and use it in GitHub Desktop.
#!/bin/sh | |
set -u | |
set -e | |
umask 0077 | |
prefix="/opt/openssh" | |
top="$(pwd)" | |
root="$top/root" | |
build="$top/build" | |
export CPPFLAGS="-I$root/include -L." | |
rm -rf "$root" "$build" | |
mkdir -p "$root" "$build" | |
gzip -dc dist/zlib-*.tar.gz |(cd "$build" && tar xf -) | |
cd "$build"/zlib-* | |
./configure --prefix="$root" --static | |
make | |
make install | |
cd "$top" | |
gzip -dc dist/openssl-*.tar.gz |(cd "$build" && tar xf -) | |
cd "$build"/openssl-* | |
./config --prefix="$root" no-shared | |
make | |
make install | |
cd "$top" | |
gzip -dc dist/openssh-*.tar.gz |(cd "$build" && tar xf -) | |
cd "$build"/openssh-* | |
cp -p "$root"/lib/*.a . | |
[ -f sshd_config.orig ] || cp -p sshd_config sshd_config.orig | |
sed \ | |
-e 's/^#\(PubkeyAuthentication\) .*/\1 yes/' \ | |
-e '/^# *Kerberos/d' \ | |
-e '/^# *GSSAPI/d' \ | |
-e 's/^#\([A-Za-z]*Authentication\) .*/\1 no/' \ | |
sshd_config.orig \ | |
>sshd_config \ | |
; | |
./configure --prefix="$prefix" --with-privsep-user=nobody --with-privsep-path="$prefix/var/empty" | |
make | |
#make install | |
cd "$top" |
I also fix some issues with original script. My version:
#!/usr/bin/env bash
set -uex
umask 0077
ZLIB_VERSION=1.2.11
OPENSSL_VERSION=1.1.1k
OPENSSH_VERSION=V_8_5_P1
prefix="/opt/openssh"
top="$(pwd)"
root="$top/root"
build="$top/build"
dist="$top/dist"
export CPPFLAGS="-I$root/include -L. -fPIC"
export CFLAGS="-I$root/include -L. -fPIC"
export LDFLAGS="-L$root/lib"
rm -rf "$root" "$build" "$dist"
mkdir -p "$root" "$build" "$dist"
curl --output $dist/zlib-$ZLIB_VERSION.tar.gz --location https://zlib.net/zlib-$ZLIB_VERSION.tar.gz
gzip -dc $dist/zlib-*.tar.gz |(cd "$build" && tar xf -)
cd "$build"/zlib-*
./configure --prefix="$root" --static
make
make install
cd "$top"
curl --output $dist/openssl-$OPENSSL_VERSION.tar.gz --location https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz
gzip -dc $dist/openssl-*.tar.gz |(cd "$build" && tar xf -)
cd "$build"/openssl-*
./config --prefix="$root" no-shared
make
make install
cd "$top"
curl --output $dist/openssh-$OPENSSH_VERSION.tar.gz --location https://github.com/openssh/openssh-portable/archive/refs/tags/$OPENSSH_VERSION.tar.gz
gzip -dc $dist/openssh-*.tar.gz |(cd "$build" && tar xf -)
cd "$build"/openssh-*
cp -p "$root"/lib/*.a .
[ -f sshd_config.orig ] || cp -p sshd_config sshd_config.orig
sed \
-e 's/^#\(PubkeyAuthentication\) .*/\1 yes/' \
-e '/^# *Kerberos/d' \
-e '/^# *GSSAPI/d' \
-e 's/^#\([A-Za-z]*Authentication\) .*/\1 no/' \
sshd_config.orig \
>sshd_config \
;
autoreconf
./configure --enable-static LIBS="-lpthread" --prefix="$root" --with-privsep-user=nobody --with-privsep-path="$prefix/var/empty"
make
#make install
cd "$top"
After:
ldd sshd
linux-vdso.so.1 (0x00007fff1e0a8000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f624e0c9000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f624e0c4000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f624e0a1000)
libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007f624e066000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f624de74000)
/lib64/ld-linux-x86-64.so.2 (0x00007f624e4d0000)
configure: WARNING: unrecognized options: --enable-static
Install build dependencies
apt update && apt install -y curl gcc make autoconf
Binaries produced
0755:ssh
0755:scp
0755:ssh-add
0755:ssh-agent
0755:ssh-keygen
0755:ssh-keyscan
0755:sshd
4711:ssh-keysign
0755:ssh-pkcs11-helper
0755:ssh-sk-helper
0755:sftp
0755:sftp-server
Oneliner list:
ssh scp ssh-add ssh-agent ssh-keygen ssh-keyscan sshd ssh-keysign ssh-pkcs11-helper ssh-sk-helper sftp sftp-server
Updated to latest libraries (up to OpenSSH 9.6p1), modified for building openssh, added some if for debugging
#!/usr/bin/env bash
set -uex
umask 0077
ZLIB_VERSION=1.3
OPENSSL_VERSION=3.2.0
OPENSSH_VERSION=V_9_6_P1
prefix="/opt/openssh"
top="$(pwd)"
root="$top/root"
build="$top/build"
dist="$top/dist"
export "CPPFLAGS=-I$root/include -L. -fPIC"
export "CFLAGS=-I$root/include -L. -fPIC"
export "LDFLAGS=-L$root/lib -L$root/lib64"
#COMMENT THIS for debugging the script. Each stage will cache download and build
#rm -rf "$root" "$build" "$dist"
mkdir -p "$root" "$build" "$dist"
if [ ! -f "build/zlib-$ZLIB_VERSION/minigzip" ]; then
echo "---- Building ZLIB -----"
if [ ! -f "$dist/zlib-$ZLIB_VERSION.tar.gz" ]; then
curl --output $dist/zlib-$ZLIB_VERSION.tar.gz --location https://zlib.net/zlib-$ZLIB_VERSION.tar.gz
gzip -dc $dist/zlib-*.tar.gz |(cd "$build" && tar xf -)
fi
cd "$build"/zlib-*
./configure --prefix="$root" --static
make
make install
cd "$top"
fi
if [ ! -f "build/openssl-$OPENSSL_VERSION/wow" ]; then
echo "---- Building OpenSSL -----"
if [ ! -f "$dist/openssl-$OPENSSL_VERSION.tar.gz" ]; then
curl --output $dist/openssl-$OPENSSL_VERSION.tar.gz --location https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz
gzip -dc $dist/openssl-*.tar.gz |(cd "$build" && tar xf -)
fi
cd "$build"/openssl-*
./config --prefix="$root" no-shared no-tests
make
make install
cd "$top"
fi
if [ ! -f "$dist/openssh-$OPENSSH_VERSION.tar.gz" ]; then
curl --output $dist/openssh-$OPENSSH_VERSION.tar.gz --location https://github.com/openssh/openssh-portable/archive/refs/tags/$OPENSSH_VERSION.tar.gz
fi
gzip -dc $dist/openssh-*.tar.gz |(cd "$build" && tar xf -)
cd "$build"/openssh-*
cp -p "$root"/lib/*.a .
[ -f sshd_config.orig ] || cp -p sshd_config sshd_config.orig
sed \
-e 's/^#\(PubkeyAuthentication\) .*/\1 yes/' \
-e '/^# *Kerberos/d' \
-e '/^# *GSSAPI/d' \
-e 's/^#\([A-Za-z]*Authentication\) .*/\1 no/' \
sshd_config.orig \
>sshd_config \
;
export PATH=$root/bin:$PATH
autoreconf
./configure LIBS="-lpthread" "--prefix=$root" "--exec-prefix=$root" --with-privsep-user=nobody --with-privsep-path="$prefix/var/empty" "--with-ssl-dir=$root"
make
cd "$top"
And my sloppy patch for CentOS 6.
It'd be nice to know what's wrong there (old autoconf?).
#!/usr/bin/env bash
set -uex
umask 0077
ZLIB_VERSION=1.3
OPENSSL_VERSION=1.1.1w
OPENSSH_VERSION=V_9_6_P1
prefix="/opt/openssh"
top="$(pwd)"
root="$top/root"
build="$top/build"
dist="$top/dist"
export "CPPFLAGS=-I$root/include -L. -fPIC"
export "CFLAGS=-I$root/include -L. -fPIC"
export "LDFLAGS=-L$root/lib -L$root/lib64"
#COMMENT THIS for debugging the script. Each stage will cache download and build
#rm -rf "$root" "$build" "$dist"
mkdir -p "$root" "$build" "$dist"
if [ ! -f "build/zlib-$ZLIB_VERSION/minigzip" ]; then
echo "---- Building ZLIB -----"
if [ ! -f "$dist/zlib-$ZLIB_VERSION.tar.gz" ]; then
curl --output $dist/zlib-$ZLIB_VERSION.tar.gz --location https://zlib.net/zlib-$ZLIB_VERSION.tar.gz
gzip -dc $dist/zlib-*.tar.gz |(cd "$build" && tar xf -)
fi
cd "$build"/zlib-*
./configure --prefix="$root" --static
make
make install
cd "$top"
fi
if [ ! -f "build/openssl-$OPENSSL_VERSION/wow" ]; then
echo "---- Building OpenSSL -----"
if [ ! -f "$dist/openssl-$OPENSSL_VERSION.tar.gz" ]; then
curl --output $dist/openssl-$OPENSSL_VERSION.tar.gz --location https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz
gzip -dc $dist/openssl-*.tar.gz |(cd "$build" && tar xf -)
fi
cd "$build"/openssl-*
./config --prefix="$root" no-shared no-tests
make
make install
cd "$top"
fi
if [ ! -f "$dist/openssh-$OPENSSH_VERSION.tar.gz" ]; then
curl --output $dist/openssh-$OPENSSH_VERSION.tar.gz --location https://github.com/openssh/openssh-portable/archive/refs/tags/$OPENSSH_VERSION.tar.gz
fi
gzip -dc $dist/openssh-*.tar.gz |(cd "$build" && tar xf -)
cd "$build"/openssh-*
cp -p "$root"/lib/*.a .
DISTRO_REL=`cat /etc/*release | tail -n1`
case "$DISTRO_REL" in
CentOS\ release\ 6*) sed -i '/.*OSSH_CHECK_CFLAG_COMPILE[(].*/d' ./configure.ac;
sed -i '/.*OSSH_CHECK_LDFLAG_LINK[(].*/d' ./configure.ac;
sed -i '/.*OSSH_CHECK_CFLAG_LINK[(].*/d' ./configure.ac;
sed -i '/.*OSSH_CHECK_HEADER_FOR_FIELD[(].*/d' ./configure.ac;
sed -i 's/[[] []]/\[\"\"\]/g' ./configure.ac;
;;
*) ;;
esac
[ -f sshd_config.orig ] || cp -p sshd_config sshd_config.orig
sed \
-e 's/^#\(PubkeyAuthentication\) .*/\1 yes/' \
-e '/^# *Kerberos/d' \
-e '/^# *GSSAPI/d' \
-e 's/^#\([A-Za-z]*Authentication\) .*/\1 no/' \
sshd_config.orig \
>sshd_config \
;
export PATH=$root/bin:$PATH
autoreconf
./configure LIBS="-pthread" "--prefix=$root" "--exec-prefix=$root" --with-privsep-user=nobody --with-privsep-path="$prefix/var/empty" "--with-ssl-dir=$root"
make
cd "$top"
为啥openssh没有make install
Improved version:
- Build OpenSSH really static this time
- Lot's of checks
- Some bugfixes
- Remove unnecessary code (including messing with sshd_config)
- Less assumptions
- Readable code
- Build() function to skip things that happen multiple times
- Comments to clarify what happens
- Versions updated
- Warn before running
#!/usr/bin/env sh
ZLIB_VERSION=1.3.1
OPENSSL_VERSION=3.2.0
OPENSSH_VERSION=V_9_6_P1
prefix="/opt/openssh" # Installation directory of OpenSSH
top="$(pwd)" # Directory where we will download and compile everything (current directory)
root="$top/root" # Subdirectory where we will install everything.
build="$top/build" # Subdirectory where we will compile everything.
dist="$top/dist" # Subdirectory where we will download everything.
ZLIB_DIR="zlib-${ZLIB_VERSION}"
ZLIB_TGZ="$ZLIB_DIR.tar.gz"
ZLIB_URL="https://zlib.net/${ZLIB_TGZ}"
ZLIB_CHECKFILE="lib/libz.a"
#Make sure it ends up in $root/lib(64), --static is needed because zlib doesn't like that you build static if you don't mention it before
ZLIB_BUILD_COMMANDS="./configure --prefix=\"$root\" --static && make && make install"
OPENSSL_DIR="openssl-${OPENSSL_VERSION}"
OPENSSL_TGZ="$OPENSSL_DIR.tar.gz"
OPENSSL_URL="https://www.openssl.org/source/${OPENSSL_TGZ}"
OPENSSL_CHECKFILE="bin/openssl"
OPENSSL_BUILD_COMMANDS="./config --prefix=\"$root\" no-tests && make && make install" #Make sure it ends up in $root/lib(64) and don't waste time with tests
OPENSSH_DIR="openssh-portable-${OPENSSH_VERSION}"
OPENSSH_TGZ="$OPENSSH_DIR.tar.gz"
OPENSSH_URL="https://github.com/openssh/openssh-portable/archive/refs/tags/${OPENSSH_VERSION}.tar.gz"
OPENSSH_CHECKFILE="bin/ssh"
#Make sure it ends up in $root/bin, that it drops privileges and that it should use the OpenSSL instead of the one that comes with the ssh source code
OPENSSH_BUILD_COMMANDS="autoreconf && ./configure --prefix=\"$root\" --exec-prefix=\"$root\" --with-privsep-user=nobody --with-ssl-dir=\"$root\" && make && make install"
read -p "We will be working in $top, things might get messy (t)here. Press Ctrl+C to cancel now or Enter to continue" ignorethisvariable
set -uex # Show each command before executing it and exits when a command returns a non-zero exit code or a variable is used without being set
umask 0077 # Make sure that no one except the owner can read, write, or execute newly created files
export "CPPFLAGS=-I$root/include -L. -fPIC -pthread"; export "CFLAGS=$CPPFLAGS" # Compiler will look for headers in $root/include, libraries in the current directory and generate position-independent code and use pthreads
export "LDFLAGS=-L$root/lib -L$root/lib64 -static" # Linker will look for libraries in $root/lib and $root/lib64 and link statically
#Check if everything needed is available
autoreconf --version || { echo "You still need to install autoconf"; exit 1; }
aclocal --version || { echo "You still need to install automake"; exit 1; }
curl --version || { echo "You still need to install curl"; exit 1; }
perl -v || { echo "You still need to install perl"; exit 1; } # OpenSSL's ./configure needs perl
make --version || { echo "You still need to install make"; exit 1; }
gcc --version || { echo "You still need to install gcc"; exit 1; }
[ -f /usr/include/linux/mman.h ] || { echo "You don't have the Linux kernel headers installed"; exit 1; }
echo "#include <stdio.h>" | gcc -E - -o /dev/null || { echo "You still need to install the C library development files"; exit 1; }
mkdir -p "$root" "$build" "$dist" # Create directories if they don't exist
build() {
local name="$1"; local version="$2"; local dir="$3"; local tgz="$4"; local url="$5"; local checkfile="$6"; local buildcommands="$7"
if [ ! -f "$root/$checkfile" ]; then # Only skip this stage if we have already have a correctly $name $version
echo "---- Building $name $version -----"
rm -rf "$build/$dir" # Remove garbage from previous failed builds
if [ ! -f "$dist/$tgz" ]; then # If we didn't download the source code yet
curl --output $dist/$tgz --location $url # Download the source code
fi
tar -C $build -xzf $dist/$tgz || { echo "Extracting $dist/$tgz failed, probably because the download failed"; exit 1; } # Extract the source code
cd "$build"/$dir
eval $buildcommands || { echo "Building $name $version failed"; exit 1; }
else
echo "---- We already have $name $version -----"
fi
cd "$top"
}
build "ZLIB" "$ZLIB_VERSION" "$ZLIB_DIR" "$ZLIB_TGZ" "$ZLIB_URL" "$ZLIB_CHECKFILE" "$ZLIB_BUILD_COMMANDS"
build "OpenSSL" "$OPENSSL_VERSION" "$OPENSSL_DIR" "$OPENSSL_TGZ" "$OPENSSL_URL" "$OPENSSL_CHECKFILE" "$OPENSSL_BUILD_COMMANDS"
build "OpenSSH" "$OPENSSH_VERSION" "$OPENSSH_DIR" "$OPENSSH_TGZ" "$OPENSSH_URL" "$OPENSSH_CHECKFILE" "$OPENSSH_BUILD_COMMANDS"
echo "Everything done. You can find the statically linked OpenSSH binaries in $root/bin"
@ngaro not working on ubuntu 2004 ZLIB_VERSION=1.3.1 OPENSSL_VERSION=3.4.0 OPENSSH_VERSION=V_9_9_P1
Building OpenSSH V_9_9_P1 failed
/usr/bin/ld: ./libssh.a(ssh-pkcs11.o): in function `pkcs11_register_provider':
ssh-pkcs11.c:(.text+0x4873): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: ./libssh.a(misc.o): in function `subprocess':
misc.c:(.text+0x7dc2): warning: Using 'initgroups' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: ./libssh.a(misc.o): in function `tilde_expand':
misc.c:(.text+0x2c73): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: ssh.o: in function `main':
ssh.c:(.text+0x1cba): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: ssh.o: in function `resolve_host':
ssh.c:(.text+0x48c): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/hgmSi/root/lib64/libcrypto.a(libcrypto-lib-bio_sock.o): in function `BIO_gethostbyname':
bio_sock.c:(.text+0x3ca): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: readconf.o: in function `default_ssh_port':
readconf.c:(.text+0xb0c): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/hgmSi/root/lib64/libcrypto.a(libcrypto-lib-dso_dlfcn.o): in function `dlfcn_pathbyaddr':
dso_dlfcn.c:(.text+0x88b): undefined reference to `dladdr'
collect2: error: ld returned 1 exit status
make: *** [Makefile:215: ssh] Error 1
+ echo Building OpenSSH V_9_9_P1 failed
+ exit 1
Thanks a lot for your script, you saved my life :-) RHEL 9.5 native ssh breaks connecting to the ILO of an HP server, I had to recompile a statically linked more recent version.
should also add
export CFLAGS="-I$root/include -L. -fPIC"
and add-fPIC
to CPPFLAGS and change--prefix="$root"
in line 43. Thank you for sharing.