晚上没事干,想着能不能把高大上的openSSH移植到我现在开发的嵌入式Linux开发板上,前不久刚弄出来dropbear,但遇到一些小问题,一会说,所以把openSSH搞上去还是可以的。开发板端为服务器端,由宿主机客户端访问。 2016-8-16
~ # mkdir /usr/local/openssl
~ # ./Configure --prefix=/usr/local/openssl os/compiler:arm-fsl-linux-gnueabi-gcc
~ # make
~ # make install
~ # mkdir /usr/local/openssh
~ # ./configure --host=arm-linux --prefix=/usr/local/openssh --with-zlib=/usr/local/zlib --with-ssl-dir=/usr/local/openssl --disable-etc-default-login --disable-strip CC=arm-fsl-linux-gnueabi-gcc AR=arm-fsl-linux-gnueabi-ar
/usr/local/openssh
并没有作用,openssh是要运行在开发机的,在宿主机中make
install
没有意义,这里是习惯性做法。另外,网上的技术帖子说将本地的路径作为打包路径一并打包,也是一种做法,但我认为略显麻烦或混乱,我最终是用脚本按部署所有的openssh工具的。
第二句命令配置configure,其中--disable-etc-default-login
是disable
using PATH from /etc/default/login no
; --disable-strip
是disable
calling strip(1) on install
,不大清楚有啥用,先记着了。第一次编译时没有添加这个参数,但最终还是设置成功了。
然后接着,在openssh源码路径下:
~ # make
make install
,上边说过。据我印象,这次make会产生一些问题,都是与设置交叉编译链有关系的,如果遇到问题,就在Makefile文件中做对应的修改。
/usr/local/openssh/bin
/usr/local/openssh/etc
/usr/local/libexec
/var/run
/var/empty
/usr/local/openssh/bin
目录下:
scp sftp ssh ssh-add ssh-agent ssh-keygen ssh-keyscan
/usr/local/openssh/etc
目录下:
moduli ssh_config sshd_config
/usr/local/libexec
目录下:
sftp-server ssh-keysign
sftp-server
拷贝到/usr/libexec
路径下,与sshd_config
配置文件的设置默认路径相匹配,我没有实际试过,但应该是这样的,下边会有详细叙述。
以下文件拷贝到开发机/etc/rc.d/init.d
目录下:
sshd
/etc/rc.d/init.d
路径下,默认是一些脚本文件,包装调用对应同名二进制程序的脚本,增加一些文件判断,启停命令,而不是直接调用二进制程序,我们这里把二进制文件放在这里,是可以实现功能的,但做法不完全合理。一种做法是,将sshd
文件拷贝到/sbin/sshd
目录下,而在/etc/rc.d/init.d
目录下添加一个脚本文件,同名,脚本内容见文末。(我是按照补充部分的做法实现的)
另注:将二进制程序放到/etc/rc.d/init.d
中,而在/sbin
目录中增加软链接的方式,不是错误的,也有这么做的,比如busybox
程序在/sbin
目录下建立了所有相关程序的软连接到/bin/busybox
,是可以实现的,个人投其所好吧。
建立软链接:
~ # cd /bin
~/bin # ln -s /usr/local/openssh/bin/scp
~/bin # ln -s /usr/local/openssh/bin/sftp
~/bin # ln -s /usr/local/openssh/bin/ssh
~/bin # ln -s /usr/local/openssh/bin/ssh-add
~/bin # ln -s /usr/local/openssh/bin/ssh-agent
~/bin # ln -s /usr/local/openssh/bin/ssh-keygen
~/bin # ln -s /usr/local/openssh/bin/ssh-keyscan
~ # cd /sbin
~/sbin # ln -s /etc/rc.d/init.d/sshd
~/sbin # ln -s /etc/rc.d/init.d/sshd
是对的,但有另一种方案,如上边8-19
补充
所述。
~ # addgroup sshd
~ # adduser -G sshd -g 'sshd privsep' -h /var/empty -s /bin/ssh sshd
/etc/passwd
文件,或给sshd重新设定密码。这一步可以暂时不做,往下看。
在目标机上产生证书密码对:
~ # cd /usr/local/openssh/etc/
~/usr/local/openssh/etc # ssh-keygen -t rsa1 -f ssh_host_key -N ""
~/usr/local/openssh/etc # ssh-keygen -t rsa -f ssh_host_rsa_key -N ""
~/usr/local/openssh/etc # ssh-keygen -t dsa -f ssh_host_dsa_key -N ""
~/usr/local/openssh/etc # ssh-keygen -t ecdsa -f ssh_host_ecdsa_key -N ""
~/usr/local/openssh/etc # ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N ""
etc
目录下产生很多密码对,另外,这里遇到一个问题,我配置ssh-keygen
-t rsa1 -f ssh_host_key -N ""
时,始终不成功,未解决。
8-19猜测 :经猜测,我认为是我使用的openSSH版本过高,不再支持ssh1的key,也是软件为了安全考虑吧。
现在执行:
/sbin/sshd
../init.d/sshd
,查资料知,ssh担心用户恶意修改出同名文件的程序替换真实的sshd而造成安全问题,要求用户调用ssh必须完整地址。这个配置应该可以从某个地方取消,我还没研究。
另外可以增加启动项,使openssh开机启动。开机启动我是这么做的:
编辑/etc/rc.d/rc.conf
文件,在其中cfg_services
项中增加:
sshd network
cfg_services_r
项中增加对应的相反内容。因为ssh要自动联网,所以我把network
也一并记在这里。
然后在文件下边增加:
export SYSCFG_IFACE0=y
export INTERFACE0="eth0"
export IPADDR0="192.168.1.33"
export NETMASK0="255.255.255.0"
export BROADCAST0="192.168.1.255"
export GATEWAY0="192.168.1.1"
#export NAMESERVER0="202.102.224.68" #dns
/etc/rc.d/init.d/network
中会自动连接网络。
~ # cd /usr/local/openssh/etc
~/usr/local/openssh/etc # vi sshd_config
PermitRootLogin yes
~ # passwd root
WARNING: Your password has expired.
You must change your password and login again!
,解决办法是,手动修改/etc/shadow
文件,如下:
root:......:11851:5:99999:7:5:20000:
sshd:......:11851:5:99999:7:5:20000:
11851
这块在你的板子上是0
,就不能通过SSH安全标准,可以试着改成和下边其他账户一样的数字。网上还说将运行有openssh的宿主机的/etc/passwd
/etc/shadow
group
文件复制到开发板/etc
目录下,同时将passwd
中的root行最末尾/bin/bash
改为/bin/sh
,也可以解决这个问题。我未尝试,有待验证。
后来遇到一个问题,ssh登录正常,但sftp无法登录,查阅网络资料,后来找到了问题的解决方案。
查看配置文件sshd_config
:
~ # cd /usr/local/openssh/etc
~/usr/local/openssh/etc # vi sshd_config
Subsystem sftp /usr/libexec/sftp-server
sftp-server
路径不同,我的路径是/usr/local/libexec/sftp-server
,可能他这个是正确的吧,修改自己的sftp-server
到配置文件中的路径或者修改配置文件中的路径到自己这个文件的路径,都可以解决这个问题。
ssh root@192.168.1.32
登录,root为用户名,后接ssh服务器ip地址。
ssh-keygen -t rsa1 -f ssh_host_key -N ""
时始终不成功,提示:Saving
key "ssh_host_key" failed: unknown or unsupported key type
,但配置其他几个key都成功了。未解决。WARNING: Your password has expired. You must change your pasword and login again!
。已解决,解决方案如上。connect close
。问题已解决,解决方案如上。#!/bin/sh
# This is the start/stop/restart script for the openSSH server daemon "sshd"
#
# before this script run, you should modify that sshd binary software is already
# placed in /sbin/sshd directory.
#
# Please put this script in /etc/rc.d/init.d/sshd and give it executable permission.
#
# 2016-8-19
# created by PWE LiumingYang, email is dicksonliuming@gmail.com
#
Exitcode=0
Sshd="/sbin/sshd"
Keygen="/usr/local/openssh/bin/ssh-keygen"
Rsa1key="/usr/local/openssh/etc/ssh_host_key"
Rsakey="/usr/local/openssh/etc/ssh_host_rsa_key"
Dsakey="/usr/local/openssh/etc/ssh_host_dsa_key"
Ecdsakey="/usr/local/openssh/etc/ssh_host_ecdsa_key"
Ed25519key="/usr/local/openssh/etc/ssh_host_ed25519_key"
func_rsa1_keygen()
{
if [ ! -s $Rsa1key ]
then
echo "generating ssh1 rsa host key..."
if $Keygen -q -t rsa1 -f $Rsa1key -N "" > /dev/null 2>&1
then
/bin/chmod 600 $Rsa1key
/bin/chmod 644 $Rsa1key.pub
echo "ssh1 rsa host key done"
else
echo "failed to generate ssh1 rsa host key"
fi
fi
}
func_rsa_keygen()
{
if [ ! -s $Rsakey ]
then
echo "generating ssh2 rsa host key..."
if $Keygen -q -t rsa -f $Rsakey -N "" > /dev/null 2>&1
then
/bin/chmod 600 $Rsakey
/bin/chmod 644 $Rsakey.pub
echo "ssh2 rsa host key done"
else
echo "failed to generate ssh2 rsa host key"
fi
fi
}
func_dsa_keygen()
{
if [ ! -s $Dsakey ]
then
echo "generating ssh2 dsa host key..."
if $Keygen -q -t dsa -f $Dsakey -N "" > /dev/null 2>&1
then
/bin/chmod 600 $Dsakey
/bin/chmod 644 $Dsakey.pub
echo "ssh2 dsa host key done"
else
echo "failed to generate ssh2 dsa host key"
fi
fi
}
func_ecdsa_keygen()
{
if [ ! -s $Ecdsakey ]
then
echo "generating ssh2 ecdsa host key..."
if $Keygen -q -t ecdsa -f $Ecdsakey -N "" > /dev/null 2>&1
then
/bin/chmod 600 $Ecdsakey
/bin/chmod 644 $Ecdsakey.pub
echo "ssh2 ecdsa host key done"
else
echo "failed to generate ssh2 ecdsa host key"
fi
fi
}
func_ed25519_keygen()
{
if [ ! -s $Ed25519key ]
then
echo "generating ssh2 ed25519 host key..."
if $Keygen -q -t ed25519 -f $Ed25519key -N "" > /dev/null 2>&1
then
/bin/chmod 600 $Ed25519key
/bin/chmod 644 $Ed25519key.pub
echo "ssh2 ed25519 host key done"
else
echo "failed to generate ssh2 ed25519 host key"
fi
fi
}
case "$1" in
start)
echo "sshd create keys:"
#ssh1 rsa is not supported in openSSH new version
#func_rsa1_keygen
func_rsa_keygen
func_dsa_keygen
func_ecdsa_keygen
func_ed25519_keygen
echo "starting sshd:"
$Sshd
Exitcode=$?
;;
stop)
echo "stopping sshd:"
/bin/killall $Sshd
Exitcode=$?
;;
restart)
echo "restarting sshd:"
/bin/killall $Sshd
$Sshd
Exitcode=$?
;;
*)
echo "Usage: sshd {start|stop|restart}"
Exitcode=1
esac
exit $Exitcode
#End sshd