项目需要,搭建lnmp环境。
了解到之前的openssl曝出的heartbleed漏洞,所以一直想升级到最新的openssl版本以保证安全(其实未必安全。。。强迫症吧)这次服务器是采用微软Azure 的Centos7.3系统。中间走过很多坑,每次出问题都重置操作系统实在是无奈,所以记录下这次经历,以便日后查阅。
实际上,整个过程看下来,还是要好好系统学习一下Linux 。 还有编译的原理。
环境
Centos7.3 x64
lnmp一键安装包oneinstack。项目官网:Oneinstack
xshell + xftp + git for windows
一、升级操作系统安装包
$ yum update -y
二、升级内核到最新并开启tcp_bbr
之前在搬瓦工搭建ss,速度到晚上一直不理想,了解到加速软件,再了解到tcp_bbr 。这是个巨大的特性。实测可以使墙外访问速度提升10倍以上,具体原理可以去查查。这个特性只有升级到Linux 4.9内核之后才支持,所以惯例升级下。
要在 CentOS 上安装最新的内核版本,我们需要增加一个 ELRepo 源。首先,让我们添加 ELRepo GPG key:
$ rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
再添加 RHEL-6,SL-7,CentOS-7 源:
$ rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
最后,安装 kernel 4.10(目前最新内核版本)
$ yum --enablerepo=elrepo-kernel install kernel-ml
查看当前操作系统内有多少个内核
$ awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg
可以看到刚才新装的4.10内核排在第一位,所以修改下系统之后启动的内核为第一个
$ grub2-set-default 0
然后修改下/etc/sysctl.conf 文件,使得一些tcp_bbr参数在重启后生效
$ echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
$ echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
重启操作系统
$ reboot
重启后查看当前操作系统的内核
$ uname -a
如果是4.10内核,那么查看当前是否以启用tcp_bbr
$ lsmod | grep tcp_bbr
不出意外的话,现在已经可以看到tcp_bbr的进程了。
配置一个新用户
其实我是为了新建一个home目录,以便待会下载各种源码包。
$ useradd test
给test用户sudo的权限,以便需要的时候提权
$ vim /etc/sudoers
找到这个文件里面的 root ALL=(ALL) ALL ,在这一行下面加一行一样的
test ALL=(ALL) ALL
wq! 保存退出
配置ssh免密登录
此时回到test用户的家目录 /home/test ,配置下密钥,待会可以免密登陆到系统。
$ mkdir .ssh
$ cd .ssh/
$ touch authorized_keys
$ chown test:test authorized_keys
$ chmod 600 authorized_keys
$ cd ../
$ cdown -R test:test .ssh
$ chmod 700 .ssh
此时在本地电脑上使用git bash生成一个公钥密钥对
$ ssh-keygen -t rsa
然后你就可以在电脑的C盘用户目录下找到一个.ssh文件夹,里面有刚刚生成的id_rsa, id_rsa.pub文件,在xshell顶部操作栏打开xftp,把刚生成的id_rsa.pub文件上传到/home/test目录下。
此时回到xsehll,输入命令
$ cat /home/test/id_rsa.pub >> /home/test/.ssh/authorized_keys
这样就把公钥里面的文件写到了test用户的authorized_keys文件里面。刚才已经把权限都配置好了,所以按道理是可以直接xshell新建一个窗口,然后测试ssh免密登陆了(需要在xsehll的会话属性里面配置下私钥,不然xsehll不知道你要用哪个文件去登陆)
不过,我们还是需要加强一下ssh的安全性。
增强ssh的安全性
修改ssh的配置文件/etc/ssh/sshd_config
$ vim /etc/ssh/sshd_config
#找到以下几项,并按照我的修改
PermitRootLogin no #禁止root登陆
StrictModes yes #开启严格模式,审查刚才的600 700权限
RSAAuthentication yes #开启私钥验证
PubkeyAuthentication yes #开启公钥验证
AuthorizedKeysFile .ssh/authorized_keys #验证文件的位置
PermitEmptyPasswords no #禁止空密码登陆
PasswordAuthentication no #禁止密码登陆,应该是只能密钥登陆了
AllowUsers test #允许test用户登陆ssh
好了,保存退出之后,直接重启ssh服务(最好先开其他窗口测试下能否免密登陆再做这一步,否则待会可能就连不上了)
$ systemctl restart sshd
好了,以上是一些基本步骤,做完之后进入安装正题,开始装lnmp环境。
下载oneinstack安装包
$ cd /home/test
$ wget http://mirrors.linuxeye.com/oneinstack-full.tar.gz #我是国外服务器所以采用这个地址
$ tar xzf oneinstack-full.tar.gz
$ cd oneinstack
$ yum -y install screen #这个screen是个窗口,可以解决Linux命令只能一个屏幕显示,不知道怎么切换到别的窗口看其他进程,而且screen支持你睡个觉再起来看里面的进程状态。不像shell关掉之后就看不到里面发生了什么
注意事项
因为踩过坑,所以知道这个一键安装包即将给我安装的是怎样的环境。我这里主要想解决的是:
想让nginx编译最新的openssl,并且支持http2
想让php编译最新的openssl,并且支持http2
让curl编译最新的openssl,并且支持http2
一键安装包虽然都是源码编译,但是编译的时候链接的是系统默认的openssl 1.0.1e ,所以需要研究一键安装包的源代码。其中研究过程就不赘述了。。有兴趣的可以自己一个文件一个文件打开看。总之这个oneinstack写的还是非常不错的。。简直把运维人员当小白了。。什么事都干好了。。
根据我的研究,整个oneinstack 需要修改以下几个文件:(点击可查看我修改后的文件,可以直接copy使用)
./options.conf
./versions.txt
./install.sh
./include/php-7.1.sh
./include/init_CentOS.sh
./include/check_sw.sh
./include/openssl.sh (这个文件其实不用改,因为用不到)
修改文件之后,在开始安装oneinstack之前,我是先手动编译安装了openssl nghttp2 curl。因为nginx和php的编译参数里面会用到这些模块。
编译安装openssl 1.1.0e
$ wget https://www.openssl.org/source/openssl-1.1.0e.tar.gz
$ tar xzf openssl-1.1.0e.tar.gz
$ cd openssl-1.1.0e
$ ./Configure linux-x86_64 shared no-ssl2 no-ssl3 no-comp enable-ec_nistp_64_gcc_128 -Wl,-rpath,/usr/local/lib64 #我是64位系统,这里我把lib库放在lib64
$ make -j 4 #4个进程进行编译,加快速度(可能)
$ make install
等待成功make install之后,到安装目录(默认是/usr/local/)
$ /usr/local/bin/openssl version
OpenSSL 1.1.0e 16 Feb 2017
$ ldd /usr/local/bin/openssl #查看加载了哪些库
linux-vdso.so.1 => (0x00007ffe2ffde000)
libssl.so.1.1 => /usr/local/lib64/libssl.so.1.1 (0x00007faabe51f000)
libcrypto.so.1.1 => /usr/local/lib64/libcrypto.so.1.1 (0x00007faabe07a000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007faabde6b000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007faabdc4f000)
libc.so.6 => /lib64/libc.so.6 (0x00007faabd88d000)
/lib64/ld-linux-x86-64.so.2 (0x000055a7f62cf000)
替换系统旧版openssl
$ mv /usr/bin/openssl /usr/bin/openssl.bak
$ mv /usr/include/openssl /usr/include/openssl.bak
$ ln -s /usr/local/bin/openssl /usr/bin/openssl
$ ln -s /usr/local/include/openssl /usr/include/openssl
$ openssl version #这里已经可以直接使用openssl命令了
OpenSSL 1.1.0e 16 Feb 2017
CFLAGS and CXXFLAGS
openssl已经升级完成了,接下来编译nghttp需要用到GCC编译器和G++编译器,需要设定CFLAGS 和 CXXFLAGS参数。
$ export CFLAGS="-I/usr/local/include/ -L/usr/local/lib -L/usr/local/lib64 -Wl,-rpath,/usr/local/lib64 -lssl -lcrypto"
$ export CXXFLAGS="-I/usr/local/include/ -L/usr/local/lib -L/usr/local/lib64 -Wl,-rpath,/usr/local/lib64 -lssl -lcrypto"
解释一下,这里面的lssl是指 libssl.so , lcryoto 是指 libcrypto.so .
因为我刚才编译openssl的时候指定的目录是/usr/local/lib64.所以这里的 -Wl,-rpath 我都指向了这个目录。
好了,现在可以编译安装nghttp2了
编译nghttp2
$ cd /home/test/oneinstack/src
$ tar xzf nghttp2-1.21.0.tar.gz
$ cd nghttp2-1.21.0
$ CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" ./configure
...
Compiler:
C compiler: gcc
CFLAGS: -I/usr/local/include/ -L/usr/local/lib -L/usr/local/lib64 -Wl,-rpath,/usr/local/lib64 -lssl -lcrypto
LDFLAGS:
C++ compiler: g++
CXXFLAGS: -I/usr/local/include/ -L/usr/local/lib -L/usr/local/lib64 -Wl,-rpath,/usr/local/lib64 -lssl -lcrypto
...
Libs:
OpenSSL: yes (CFLAGS='-I/usr/local/include' LIBS='-L/usr/local/lib64 -lssl -lcrypto')
$ make -j 4
$ make install
Libraries have been installed in:
/usr/local/lib
编译cURL
$ cd /home/test/oneinstack/src
$ tar xzf curl-7.53.1.tar.gz
$ cd curl-7.53.1
$ ./configure --with-ssl=/usr/local --with-nghttp2=/usr/local
...
configure: Configured to build curl/libcurl:
curl version: 7.51.0
Host setup: x86_64-pc-linux-gnu
Install prefix: /usr/local
Compiler: gcc
SSL support: enabled (OpenSSL)
SSH support: no (--with-libssh2)
zlib support: no (--with-zlib)
GSS-API support: no (--with-gssapi)
TLS-SRP support: enabled
resolver: default (--enable-ares / --enable-threaded-resolver)
IPv6 support: enabled
Unix sockets support: enabled
IDN support: no (--with-{libidn2,winidn})
Build libcurl: Shared=yes, Static=yes
Built-in manual: enabled
--libcurl option: enabled (--disable-libcurl-option)
Verbose errors: enabled (--disable-verbose)
SSPI support: no (--enable-sspi)
ca cert bundle: /etc/ssl/certs/ca-certificates.crt
ca cert path: no
ca fallback: no
LDAP support: no (--enable-ldap / --with-ldap-lib / --with-lber-lib)
LDAPS support: no (--enable-ldaps)
RTSP support: enabled
RTMP support: no (--with-librtmp)
metalink support: no (--with-libmetalink)
PSL support: no (libpsl not found)
HTTP2 support: enabled (nghttp2)
Protocols: DICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS POP3 POP3S RTSP SMB SMBS SMTP SMTPS TELNET TFTP
$ make -j 4
$ make install
查看curl所在位置和链接库
$ which curl
/usr/local/bin/curl
$ ldd /usr/local/bin/curl
linux-vdso.so.1 => (0x00007fff4a358000)
libssl.so.1.1 => /usr/local/lib64/libssl.so.1.1 (0x00007f6c3edfa000)
libcrypto.so.1.1 => /usr/local/lib64/libcrypto.so.1.1 (0x00007f6c3e955000)
libcurl.so.4 => /usr/local/lib/libcurl.so.4 (0x00007f6c3e6e9000)
libz.so.1 => /lib64/libz.so.1 (0x00007f6c3e4c8000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6c3e106000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f6c3df02000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f6c3dce6000)
libnghttp2.so.14 => /usr/local/lib/libnghttp2.so.14 (0x00007f6c3dab6000)
/lib64/ld-linux-x86-64.so.2 (0x000055cf5fba3000)
$ /usr/local/bin/curl -V
curl 7.53.1 (x86_64-pc-linux-gnu) libcurl/7.53.1 OpenSSL/1.1.0e zlib/1.2.7 nghttp2/1.21.0
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy
可以看到,已经支持openssl 1.1.0e 和 http2 。
更新系统链接库
现在基本完成了需要的编译工作,但是为了保证不出错,需要更新一下系统链接库。
$ echo "/usr/local/lib" >> /etc/ld.so.conf
$ echo "/usr/local/lib64" >> /etc/ld.so.conf
$ ldconfig -V #使生效
安装oneinstack
到此为止,已经完成了前期的铺垫工作,可以开始装oneinstack了。
$ cd /home/test/oneinstack
$ screen -S lnmp
$ ./install.sh
我这里的选择是:nginx-mysql5.7-php7.1.3-opacache,其他的都没装。
不出意外的话,就可以等待着安装完成了。如果中间有退出shell,再次连接之后可以通过
screen -r
打开之前的安装窗口。安装完成后重启系统即可。
先写到这里,之后的一些额外配置下次再写。
先占个位