下载openssh

wget https://cloudflare.cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.0p1.tar.gz
tar xvf openssh-9.0p1.tar.gz

编译指令

./configure --prefix=/ --host=arm-linux-gnueabihf --with-zlib=$(pwd)/.. --with-ssl-dir=$(pwd)/.. --with-libs="-lpthread" --disable-strip -with-ldflags="-Wl,-rpath /usr/lib -Wl,-rpath /lib" --disable-etc-default-login --with-privsep-user=nobody --with-privsep-path="/var/empty"

make 

注意:只make,不要make install

如果使用了--prefix指定的其他目录,会出现类似错误

scp pub.key root@192.168.1.8:/var/www/html/

/home/const/arm-compile/openssh-9.0p1/../bin/ssh: No such file or directory

如果不指定--prefix, 就会要求ssh放在/usr/local/bin/ssh目录下。

scp scp root@192.168.1.8:/var/www/html

/usr/local/bin/ssh: No such file or directory
scp: Connection closed

静态编译openssh的问题

./configure --prefix=/ --host=arm-linux-gnueabihf --with-zlib=$(pwd)/.. --with-ssl-dir=$(pwd)/.. --with-libs="-lpthread" --disable-strip -with-ldflags="-static" --disable-etc-default-login --with-privsep-user=nobody --with-privsep-path="/var/empty"

编译完成后,运行scp,会卡死无响应。

strace /bin/scp

execve("/bin/scp", ["/bin/scp"], 0x7ea03ce0 / 18 vars /) = 0
brk(NULL) = 0x115f000
brk(0x115fd0c) = 0x115fd0c
set_tls(0x115f4c0) = 0
readlink("/proc/self/exe", "/bin/scp", 4096) = 8
brk(0x1180d0c) = 0x1180d0c
brk(0x1181000) = 0x1181000
open("/dev/null", O_RDWR|O_LARGEFILE) = 3
close(3) = 0
futex(0x1e9c24, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x1e9c28, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x1e9c2c, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x1e9ee8, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x1e9c34, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x1e9c38, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x1e9cbc, FUTEX_WAKE_PRIVATE, 2147483647) = 0
getpid() = 20133
getrandom("x8axadx3fx00xd7x42xa5xcax40x16xfax2fxcexb5xe8x9cxb5x65x44x10x0dx33x18xe9xa7x3cx9ax65x17xffxdbx09", 32, 0) = 32
clock_gettime(CLOCK_REALTIME, {tv_sec=1651798290, tv_nsec=756874203}) = 0
gettimeofday({tv_sec=1651798290, tv_usec=757342}, NULL) = 0
futex(0x1e9ca4, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x1162574, FUTEX_WAIT_PRIVATE, 0, NULL

从上面可以看到futex 阻塞住了。

静态编译后的ssh可以运行.

查看静态编译依赖的动态库

arm-linux-gnueabihf-objdump -x ssh |grep NEEDED

查看动态编译依赖的动态库

arm-linux-gnueabihf-objdump -x ../bin/ssh |grep NEEDED

NEEDED libcrypto.so.1.1
NEEDED libdl.so.2
NEEDED libutil.so.1
NEEDED libz.so.1
NEEDED libpthread.so.0
NEEDED libcrypt.so.1
NEEDED libresolv.so.2
NEEDED libc.so.6
NEEDED ld-linux-armhf.so.3

这里说到一个不需要使用ldd,查看动态库依赖的方法。使用arm-linxu-gnueabihf-objdump -x scp |grep NEEDED

使用ldd的方法如下:

ldd /bin/scp

linux-vdso.so.1 (0x00007ffe21797000)
libcrypto.so.1.1 => /lib/x86_64-linux-gnu/libcrypto.so.1.1 (0x00007f0bfaadd000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0bfa8eb000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f0bfa8e5000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0bfa8c2000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0bfade7000)

objdump -x /bin/scp |grep NEEDED

NEEDED libcrypto.so.1.1
NEEDED libc.so.6

过程中出现的各种问题
scp报错 -bash: scp: command not found
此错误要求arm的scp要放在/bin/scp目录下面。

scp: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory
此错误是scp没有找到相关的动态库,要求动态库的位置在/usr/lib/arm-linux-gnueabihf/目录下。这个也是通过调试得到的。

调试scp日志的方法

/home/const/bin/strace /home/const/bin/scp -v 2

将上述命令以脚本方式保存为/bin/scp即可在对端得到调试信息。

根据上面的提示信息,我们可以将依赖设置到指定目录
gcc rpath multiple directories

-Wl,-rpath /usr/lib -Wl,-rpath /lib

这就是上面openssh编译命令中的ldflags选项。

错误提示:
OpenSSL version mismatch. Built against 10101080, you have 101010bf
scp: Connection closed

因为编译的OpenSSL版本与实际使用的版本有少少差异,导致不能使用.最好的解决办法是使用相同的版本,如果版本差异不大呢, 就修改openssh的源码.
将entropy.c文件

if (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER,
OpenSSL_version_num()))
debug3("OpenSSL version mismatch. Built against %lx, you "
"have %lx", (u_long)OPENSSL_VERSION_NUMBER,
OpenSSL_version_num());

删除或注释就可以了.

错误代码:disconnect response code 7

错误信息:The connection was lost

可能的原因是,使用了相同的clientid

在mosquitto_new 的第一个参数中,使用NULL就好。

还有另一个原因,也会出现这个错误.就是当mqtt broker重启会导致disconnect 7.

安装mosquitto borker

sudo apt-get update
sudo apt-get install mosquitto

安装mosquitto clients

sudo apt-get install mosquitto-clients

查看运行状态

systemctl status mosquitto

状态信息:

 mosquitto.service - Mosquitto MQTT v3.1/v3.1.1 Broker
 Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor pre>
 Active: active (running) since Mon 2022-05-09 16:59:13 CST; 16h ago
   Docs: man:mosquitto.conf(5)
         man:mosquitto(8)
  Main PID: 524488 (mosquitto)
  Tasks: 3 (limit: 18708)
 Memory: 1.2M
 CGroup: /system.slice/mosquitto.service
         └─524488 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

重启mqtt服务

systemctl restart mosquitto

停止mqtt服务

systemctl stop mosquitto

测试使用mqtt

mosquitto -v

1652145455: mosquitto version 1.6.9 starting
1652145455: Using default config.
1652145455: Opening ipv4 listen socket on port 1883.
1652145455: Opening ipv6 listen socket on port 1883.

启动mosquitto监听1883端口

mosquitto -p 1883

启动mosquitto后台运行监听1884端口

mosquitto -p 1884 -d

**启动mosquitto后台运行使用mosquitti-2.conf配置文件

mosquitto -c /etc/mosquitto/mosquitto-2.conf -d

Prerequisites

sudo apt-get install build-essential checkinstall
sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev
wget https://www.python.org/ftp/python/3.5.3/Python-3.5.3.tar.xz
tar xvf Python-3.5.3.tar.xz
cd Python-3.5.3
sudo ./configure --enable-optimizations
sudo make altinstall

make altinstall is used to prevent replacing the default python binary file /usr/bin/python.

python3.5 -V

Python 3.5.3

pyOpenSSL是Python的openssl库.
通过pip安装:

pip install pyOpenSSL

产生密钥对

from OpenSSL.crypto import PKey
from OpenSSL.crypto import TYPE_RSA, FILETYPE_PEM
from OpenSSL.crypto import dump_privatekey, dump_publickey

pk = PKey()
print(pk)
pk.generate_key(TYPE_RSA, 1024)
dpub = dump_publickey(FILETYPE_PEM, pk)
print(dpub)
dpri = dump_privatekey(FILETYPE_PEM, pk)
print(dpri)

运行结果:
<OpenSSL.crypto.PKey object at 0x76c3b090>
b'-----BEGIN PUBLIC KEY-----nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyNCTZuEzZrX2OaaPgcdCsd3VInPXVGyWKzCc0rUdmmrD7+czdeCgoeHuCwwkig+pGhYFYZvFNZFaEzxKmmJOTxrklBnxOk2K2mTvqsviPMFG780qG69zM+Zm+tYPy+aU4taRoPhlSY9hy2YWubKiLqUkGWXnfoJOElkGFD+O4IwsWwIDAQABn-----END PUBLIC KEY-----n'
b'-----BEGIN PRIVATE KEY-----nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALI0JNm4TNmtfY5pno+Bx0Kx3dUg9dUbJYrMJzStR2aasPv5zN14KCh4e4LDCSKD6kaFgVhm8U1kVoTPEnqaYk5PGuSUHE6TYraZO+qy+I8wUbvzSobr3Mz5mb61g/L5pTi1pGg+GVJj2HLZhan5sqIupSQZZd+gk4SWQYUP47gjCxbAgMBAAECgYEAhqYNvhCayNNlDmlV8O4uvVIZn5TbC2XSrRhq+0t+qtFxr0Llf+Ydec7njDswOMsyBo0z2YcXBuIs2XbZYdXhlH9AgnWWrkhRPVLN0mvs/XPpXRkQh233orznIgoz8UBuoUlcXppA/KOnSSJ2RuwVtiqAl5nQf71oRSVZ7AmKy6PLOECQQDofMyLSx9KWoQ/HSiw7w9lgX7+olyB3ybg+Hi9YdrhnyxWJ2VJoY5TTCCsREsAyF86fRSNuaF3PpU/6oYkT+6brAkEAxDnp8jAKmrfX8qKTnnNOwFJaAJBAihtrgeURPWGiCTSWR9w0S5w+AKeeGU9oEhuPaUK1rUdtqYlFMhAgjn2iYUUQJAEw9wQZdGGHV1VCtS07a1v2+vdrbe+LLP4C/ezkAAjvR0bpnHnNFVOTv5nM+win7i98ubbMckSr9xwwy6NK3s9QwJAU2wjr5kJCRnbrwW7J9M/aqFJPQu3AgoPnoL6P1RApRU8RrSxbuuv2GtqZWxC3F/nKmL4BgD1+DuptUzx6sYW64QJAC5jNhQw7nd1AzDBc4X8fkcOH1+fn3sNGT5UBZ5+1l8jy44QR0ZaDsbGKyWEizDiJVvC01eNJdnTDj99Venyyug6Q==n-----END PRIVATE KEY-----n'

签名与验签

from OpenSSL.crypto import PKey
from OpenSSL.crypto import TYPE_RSA, FILETYPE_PEM
from OpenSSL.crypto import sign, verify
from OpenSSL.crypto import X509

pk = PKey()
pk.generate_key(TYPE_RSA, 1024)
 
signature = sign(pk, 'hello, world!', 'sha256')
print(signature)
 
x509 = X509()
x509.set_pubkey(pk)
verify(x509, signature, 'hello, world!', 'sha256')

结果:
b'txe1xb1rxc1}x82x9dxbexa2x97x14x88xdbxf7x19x835xeb=xc0x87xa5xe9xe7x10xcdxaax90Qx11xee;oxf4Axafxa0xfcj3Xtxd9=x10xf3xbdxe9xc3>@xc1xafxffx8dxfbtxd9x81xfaxdexa2QLxc2xf0t+_wxfex1bx86x0f\xebJ\x17xcaxf4x11xb0lxd6x17`xfdx194xa6x0cxe3yx93Exd2x92Bx984-(xc8qxdax1e:,xd4x83jxca(jxe4xb5Gxa6(xfaxffx97xa2xabxa9xd6'

如果验签失败,会出现以下错误.
OpenSSL.crypto.Error: [('rsa routines', 'int_rsa_verify', 'bad signature')]