客户linux主机ssh存在高危漏洞,需要进行升级修复。

  linux联网后,直接命令行:

[root@gw ~]# yum update openssl -y

  此命令只是小版本的升级,比如将openssl从1.0.1e-43版本升级到1.0.1e-57版本,但好多时候我们需要升级的是大版本,而不是这种小的修复。

  yum remove openssl命令执行时,可以看到,非常非常多的软件是依赖于openssl软件。openssl是一个非常基础的软件。编译安装一个新版本的openssl覆盖掉操作系统自带的openssl。这就会导致那些依赖于openssl的软件的openssl相关的功能变得不可用。

  ssh命令是openssh软件的一部分。因为上面提出的现象我们不直接升级操作系统的openssl,但是我们可以另外编译一个openssl,放到单独的应用目录中,与操作系统的openssl互不影响。再基于新编译出来的openssl,将新的openssh软件编译出来。 而操作系统的openssh是可以被替换的。如果你尝试执行 yum remove openssh* 命令就可以看到,没有其它软件依赖于openssh。此外,openssh软件提供了sshd服务。所以,我们只要还要配置并搭建好sshd服务,就可以替代操作系统自带的openssh了。

  接下来我们分析,如何升级openssh及其所依赖的openssl。

从openssh官网下载openssh 7.9.p1源码包,查看里面的INSTALL文件,里面有对它的依赖关系做说明 可以依据blfs下载(http://www.linuxfromscratch.org/blfs/news.html

 

  openssh7.9p1下载安装说明,可参考解压后的install文件(http://www.linuxfromscratch.org/blfs/view/8.4/postlfs/openssh.html

1,提前检查必须安装的(Zlib、libcrypto或者(LibreSSL或OpenSSL))

  • Zlib 1.1.4或1.2.1.2或更高版本(早期1.2.x版本有问题)  http://www.gzip.org/zlib/
  • libcrypto(LibreSSL或OpenSSL> = 1.0.1 <1.1.0),这个库可以用LibreSSL或OpenSSL替代,但应该将LibreSSL / OpenSSL编译为与位置无关的库(即使用-fPIC)
    否则OpenSSH将无法与之链接。如果您必须使用非位置无关的libcrypto,那么您可能需要配置OpenSSH - without-pie。 请注意,由于API更改,目前不支持OpenSSL 1.1.x.
    LibreSSL http://www.libressl.org/; 
    OpenSSL http://www.openssl.org/

2,还有一些是可选的安装,例如PAM软件等

1. Prerequisites
---------------- A C compiler. Any C89 or better compiler should work. Where supported,
configure will attempt to enable the compiler's run-time integrity checking
options. Some notes about specific compilers:
- clang: -ftrapv and -sanitize=integer require the compiler-rt runtime
(CC=clang LDFLAGS=--rtlib=compiler-rt ./configure) You will need working installations of Zlib and libcrypto (LibreSSL /
OpenSSL) Zlib 1.1.4 or 1.2.1.2 or greater (earlier 1.2.x versions have problems):
http://www.gzip.org/zlib/ libcrypto (LibreSSL or OpenSSL >= 1.0.1 < 1.1.0)
LibreSSL http://www.libressl.org/ ; or
OpenSSL http://www.openssl.org/ LibreSSL/OpenSSL should be compiled as a position-independent library
(i.e. with -fPIC) otherwise OpenSSH will not be able to link with it.
If you must use a non-position-independent libcrypto, then you may need
to configure OpenSSH --without-pie. Note that because of API changes,
OpenSSL 1.1.x is not currently supported. The remaining items are optional. NB. If you operating system supports /dev/random, you should configure
libcrypto (LibreSSL/OpenSSL) to use it. OpenSSH relies on libcrypto's
direct support of /dev/random, or failing that, either prngd or egd PRNGD: If your system lacks kernel-based random collection, the use of Lutz
Jaenicke's PRNGd is recommended. http://prngd.sourceforge.net/ EGD: If the kernel lacks /dev/random the Entropy Gathering Daemon (EGD) is
supported only if libcrypto supports it. http://egd.sourceforge.net/ PAM: OpenSSH can utilise Pluggable Authentication Modules (PAM) if your
system supports it. PAM is standard most Linux distributions, Solaris,
HP-UX 11, AIX >= 5.2, FreeBSD and NetBSD. Information about the various PAM implementations are available: Solaris PAM: http://www.sun.com/software/solaris/pam/
Linux PAM: http://www.kernel.org/pub/linux/libs/pam/
OpenPAM: http://www.openpam.org/ If you wish to build the GNOME passphrase requester, you will need the GNOME
libraries and headers. GNOME:
http://www.gnome.org/ Alternatively, Jim Knoble <jmknoble@pobox.com> has written an excellent X11
passphrase requester. This is maintained separately at: http://www.jmknoble.net/software/x11-ssh-askpass/ LibEdit: sftp supports command-line editing via NetBSD's libedit. If your platform
has it available natively you can use that, alternatively you might try
these multi-platform ports: http://www.thrysoee.dk/editline/
http://sourceforge.net/projects/libedit/ LDNS: LDNS is a DNS BSD-licensed resolver library which supports DNSSEC. http://nlnetlabs.nl/projects/ldns/ Autoconf: If you modify configure.ac or configure doesn't exist (eg if you checked
the code out of git yourself) then you will need autoconf-2.69 to rebuild
the automatically generated files by running "autoreconf". Earlier
versions may also work but this is not guaranteed. http://www.gnu.org/software/autoconf/ Basic Security Module (BSM): Native BSM support is known to exist in Solaris from at least 2.5.1,
FreeBSD 6.1 and OS X. Alternatively, you may use the OpenBSM
implementation (http://www.openbsm.org). makedepend: https://www.x.org/archive/individual/util/ If you are making significant changes to the code you may need to rebuild
the dependency (.depend) file using "make depend", which requires the
"makedepend" tool from the X11 distribution.

安装Zlib

Zlib用于压缩和解压缩的功能。操作系统已经自带了zlib,可以查看是否符合要求。实际上,openssl和openssh都依赖于zlib。执行下面的命令,安装zlib开发包:

 rpm -qa|grep zlib
yum -y install zlib-devel

安装PAM

PAM(Pluggable Authentication Modules,可插拔认证模块)用于提供安全控制。操作系统也已经自带了PAM,版本也是可以的。执行下面的命令,安装PAM开发包:

rpm -qa|grep pam
yum -y install pam-devel

安装tcp_wrappers

tcp_wrappers是一种安全工具,通常,我们在/etc/hosts.allow或/etc/hosts.deny文件中配置的过滤规则就是使用的tcp_wrappers的功能了。openssh在编译时的确是可以选择支持tcp_wrappers的。执行下面的命令,安装tcp_wrappers开发包:

rpm -qa|grep tcp_wrappers
yum install tcp_wrappers-devel -y

系统最小化安装时,需要安装包

一般出现这个-bash: make: command not found提示,是因为安装系统的时候使用的是最小化mini安装,系统没有安装make、vim等常用命令,直接yum安装下即可。

yum -y install gcc automake autoconf libtool make

安装OpenSSL

由于OpenSSH 7.9p1要求OpenSSL的版本> = 1.0.1 <1.1.0,因此,当前符合要求的最新OpenSSL版本为1.0.2l https://www.openssl.org/source/old/1.0.2/

首先,从openssl官网下载源码包openssl-fips-2.0.16.tar.gz(https://www.openssl.org/source/old/fips/)将其安装到/opt/fips-2.0目录下。

编译安装FIPS宏(https://bbs.csdn.net/wap/topics/390830236):

mkdir /opt/fips-2.0
# export FIPSDIR=/opt/fips-2.0                 --指定另外的安装目录,默认会安装在/usr/local/ssl/fips­2.0目录
# tar -xvf openssl-fips-2.0..tar.gz
# cd openssl-fips-2.0.
# ./config
# make
# make install

从openssl官网下载源码包openssl-1.0.2l.tar.gz,将其安装到/opt/openssl1.0.2l_2019目录下。将openssl安装到专门的目录,这是为了避免对操作系统自带的openssl造成影响。

编译安装OpenSSL

mkdir /opt/openssl1.0.2l_2019
# tar -xvf openssl-1.0.2l.tar.gz
# cd openssl-1.0.2l
# ./config --prefix=/opt/openssl1..2l_2019 --openssldir=/opt/openssl1..2l_2019/openssl fips --with-fipsdir=/opt/fips-2.0 zlib-dynamic shared -fPIC
# make depend
# make
# make test
# make install
  • --prefix:指定openssl的安装目录。按本例中的安装方式,安装完成后该目录下会包含bin(含二进制程序)、lib(含动态库文件)、include/openssl(含报头文件)及openssl(--openssldir选项指定的)这些子目录。

  • --openssldir:指定openssl文件的安装目录。按本例中的安装方式,安装完成后该目录下会包括certs(存放证书文件)、man(存放man文件)、misc(存放各种脚本)、private(存放私钥文件)这些子目录及openssl.cnf配置文件。

  • fips:集成FIPS模块。

  • --with-fipsdir:指向FIPS模块的安装目录位置。

  • zlib-dynamic:编译支持zlib压缩/解压缩,让openssl加载zlib动态库。该选项只在支持加载动态库的操作系统上才支持。这是默认选项。

  • shared:除了静态库以外,让openssl(在支持的平台上)也编译生成openssl动态库。

  • -fPIC:将openssl动态库编译成位置无关(position-independent)的代码。

安装完成后,将OpenSSL的库文件目录添加到/etc/ld.so.conf文件中,并加载到系统内存缓存中:

# echo '/opt/openssl1.0.2l_2019/lib' >> /etc/ld.so.conf
# ldconfig

安装OpenSSH

从openssl官网下载源码包openssh-7.9p1.tar.gz,将其安装到/opt/openssh7.9.p1_2019目录下。将openssh安装到专门的目录,这是为了避免与操作系统自带的openssh造成不必要的冲突。

编译安装OpenSSH:

mkdir /opt/openssh7.9.p1_2019
# tar -xvf openssh-.9p1.tar.gz
# cd openssh-.9p1
# ./configure --prefix=/opt/openssh7..p1_2019 --with-ssl-dir=/opt/openssl1..2l_2019 --with-pam --with-tcp-wrappers
# make
# make install
  • --prefix:指定安装目录

  • --with-ssl-dir=DIR:指向LibreSSL/OpenSSL库的安装目录的所在路径。

  • --with-pam:启用PAM支持。根据OpenSSH的安装说明,如果在编译时启用了PAM,那么在安装完成后,也必须在sshd服务的配置文件sshd_config中启用它(使用UsePAM指令)。

根据OpenSSH的安装说明,如果有启用PAM,那么就需要手工安装一个给sshd程序使用的PAM配置文件,否则安装好OpenSSH后你可能会无法使用密码登录系统。在编译时,我使用 --with-pam 选项启用了对PAM的支持,但是,编译OpenSSH时并没有编译选项让你指定PAM配置文件的位置,那么我们要怎么提供这个配置文件呢?

事实上,OpenSSH有另外一个编译选项--with-pam-service=name可以指定PAM服务名,它的默认值是sshd。而操作系统自带的PAM软件默认将所有PAM配置文件都放置在/etc/pam.d目录下。结合这两个信息,就可确定OpenSSH的PAM配置文件应为/etc/pam.d/sshd文件。而这个文件原来就有了,所以我们不用额外手工创建一个。

设置PATH路径:

# echo 'export PATH=/opt/openssh7.9.p1_2019/bin:/opt/openssh7.9.p1_2019/sbin:$PATH' >> /etc/profile.d/path.sh
# . /etc/profile.d/path.sh

此时,使用ssh -V命令就可以看到新版本号了

ssh -V

配置OpenSSH

前面已经安装好了openssh,但是我们还需要配置它,以保证sshd服务可以启起来。我们可以先看一下原有的sshd服务(属于openssh-server软件包)都有哪些配置文件:

# rpm -ql openssh-server | grep -i --color etc
/etc/pam.d/ssh-keycat
/etc/pam.d/sshd
/etc/rc.d/init.d/sshd
/etc/ssh/sshd_config
/etc/sysconfig/sshd

可以看到,sshd服务的配置文件为/etc/ssh/sshd_config,它的pam配置文件为/etc/pam.d/sshd和/etc/pam.d/ssh-keycat,启动脚本文件为/etc/rc.d/init.d/sshd,启动脚本里面有引用到文件/etc/sysconfig/sshd。

参照系统原有的配置文件修改我们软件的sshd_config配置文件,这是sshd服务的配置文件(红色字体的为新增或修改的部分):

# vim /opt/openssh7..p1_2019/etc/sshd_config
Protocol
SyslogFacility AUTHPRIV
PermitRootLogin yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
#GSSAPIAuthentication yes //该选项目前还不支持
#GSSAPICleanupCredentials yes //该选项目前还不支持
UsePAM yes AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS X11Forwarding yes
Subsystem sftp /opt/openssh7..p1_2019/libexec/sftp-server

注意,UsePAM一定要启用,OpenSSH的安装说明里有提到,如果编译时启用了PAM支持,那么就必须在sshd_config文件中启用它。

拷贝系统原有的配置文件/etc/sysconfig/sshd到我们软件下面,这个配置文件用于设置启动sshd服务所需的环境变量,在sshd服务的启动脚本里有调用到该配置文件:

# cp -a /etc/sysconfig/sshd /opt/openssh7..p1_2019/etc/sshd

接下来要修改sshd服务的启动脚本/etc/rc.d/init.d/sshd。先将启动脚本备份一份为sshd.old,并添加至chkconfig管理:

# cp /etc/rc.d/init.d/sshd /etc/rc.d/init.d/sshd.old
# chkconfig --add sshd.old

再根据我们的OpenSSH的安装路径,来修改原有的启动脚本(红色字体为有新增或修改的部分-注:linux7之后没有这个文件,可以自己新建一个启动文件,手动添加这个服务,开机自启动等启动sshd):

修改配置文件权限

chmod u+x /etc/rc.d/init.d/sshdnew

添加sshd服务

chkconfig --add sshdnew
设置开机自启动
chkconfig sshdnew on 验证开机启动 chkconfig --list|grep sshdnew service sshdnew start systemctl is-active sshdnew
vim /etc/rc.d/init.d/sshd
#!/bin/bash
#
# sshd Start up the OpenSSH server daemon
#
# chkconfig:
# description: SSH is a protocol for secure remote shell access. \
# This service starts up the OpenSSH server daemon.
#
# processname: sshd
# config: /etc/ssh/ssh_host_key
# config: /etc/ssh/ssh_host_key.pub
# config: /etc/ssh/ssh_random_seed
# config: /etc/ssh/sshd_config
# pidfile: /var/run/sshd.pid ### BEGIN INIT INFO
# Provides: sshd
# Required-Start: $local_fs $network $syslog
# Required-Stop: $local_fs $syslog
# Should-Start: $syslog
# Should-Stop: $network $syslog
# Default-Start:
# Default-Stop:
# Short-Description: Start up the OpenSSH server daemon
# Description: SSH is a protocol for secure remote shell access.
# This service starts up the OpenSSH server daemon.
### END INIT INFO # source function library
. /etc/rc.d/init.d/functions # pull in sysconfig settings
[ -f /opt/openssh7.9.p1_2019/etc/sshd ] && . /opt/openssh7.9.p1_2019/etc/sshd RETVAL=
prog="sshd"
lockfile=/var/lock/subsys/$prog # Some functions to make the below more readable
KEYGEN=/opt/openssh7.9.p1_2019/bin/ssh-keygen
SSHD=/opt/openssh7.9.p1_2019/sbin/sshd
RSA1_KEY=/etc/ssh/ssh_host_key
RSA_KEY=/opt/openssh7.9.p1_2019/etc/ssh_host_rsa_key
DSA_KEY=/opt/openssh7.9.p1_2019/etc/ssh_host_dsa_key
PID_FILE=/var/run/sshd.pid # PID文件的所在路径,这个变量的值不要改 runlevel=$(set -- $(runlevel); eval "echo \$$#" ) fips_enabled() {
if [ -r /proc/sys/crypto/fips_enabled ]; then
cat /proc/sys/crypto/fips_enabled
else
echo
fi
} do_rsa1_keygen() {
if [ ! -s $RSA1_KEY -a `fips_enabled` -eq ]; then
echo -n $"Generating SSH1 RSA host key: "
rm -f $RSA1_KEY
if test ! -f $RSA1_KEY && $KEYGEN -q -t rsa1 -f $RSA1_KEY -C '' -N '' >&/dev/null; then
chmod $RSA1_KEY
chmod $RSA1_KEY.pub
if [ -x /sbin/restorecon ]; then
/sbin/restorecon $RSA1_KEY.pub
fi
success $"RSA1 key generation"
echo
else
failure $"RSA1 key generation"
echo
exit
fi
fi
} do_rsa_keygen() {
if [ ! -s $RSA_KEY ]; then
echo -n $"Generating SSH2 RSA host key: "
rm -f $RSA_KEY
if test ! -f $RSA_KEY && $KEYGEN -q -t rsa -f $RSA_KEY -C '' -N '' >&/dev/null; then
chmod $RSA_KEY
chmod $RSA_KEY.pub
if [ -x /sbin/restorecon ]; then
/sbin/restorecon $RSA_KEY.pub
fi
success $"RSA key generation"
echo
else
failure $"RSA key generation"
echo
exit
fi
fi
} do_dsa_keygen() {
if [ ! -s $DSA_KEY ]; then
echo -n $"Generating SSH2 DSA host key: "
rm -f $DSA_KEY
if test ! -f $DSA_KEY && $KEYGEN -q -t dsa -f $DSA_KEY -C '' -N '' >&/dev/null; then
chmod $DSA_KEY
chmod $DSA_KEY.pub
if [ -x /sbin/restorecon ]; then
/sbin/restorecon $DSA_KEY.pub
fi
success $"DSA key generation"
echo
else
failure $"DSA key generation"
echo
exit
fi
fi
} do_restart_sanity_check()
{
$SSHD -t
RETVAL=$?
if [ $RETVAL -ne ]; then
failure $"Configuration file or keys are invalid"
echo
fi
} start()
{
[ -x $SSHD ] || exit
[ -f /opt/openssh7.9.p1_2019/etc/sshd_config ] || exit
# Create keys if necessary
if [ "x${AUTOCREATE_SERVER_KEYS}" != xNO ]; then
# do_rsa1_keygen  # 注释掉这条语句
do_rsa_keygen
do_dsa_keygen
fi echo -n $"Starting $prog: "
$SSHD $OPTIONS && success || failure
RETVAL=$?
[ $RETVAL -eq ] && touch $lockfile
echo
return $RETVAL
} stop()
{
echo -n $"Stopping $prog: "
killproc -p $PID_FILE $SSHD
RETVAL=$?
# if we are in halt or reboot runlevel kill all running sessions
# so the TCP connections are closed cleanly
if [ "x$runlevel" = x0 -o "x$runlevel" = x6 ] ; then
trap '' TERM
killall $prog >/dev/null
trap TERM
fi
[ $RETVAL -eq ] && rm -f $lockfile
echo
} reload()
{
echo -n $"Reloading $prog: "
killproc -p $PID_FILE $SSHD -HUP
RETVAL=$?
echo
} restart() {
stop
start
} force_reload() {
restart
} rh_status() {
status -p $PID_FILE openssh-daemon
} rh_status_q() {
rh_status >/dev/null >&
} case "$1" in
start)
rh_status_q && exit
start
;;
stop)
if ! rh_status_q; then
rm -f $lockfile
exit
fi
stop
;;
restart)
restart
;;
reload)
rh_status_q || exit
reload
;;
force-reload)
force_reload
;;
condrestart|try-restart)
rh_status_q || exit
if [ -f $lockfile ] ; then
do_restart_sanity_check
if [ $RETVAL -eq ] ; then
stop
# avoid race
sleep
start
else
RETVAL=
fi
fi
;;
status)
rh_status
RETVAL=$?
if [ $RETVAL -eq -a -f $lockfile ] ; then
RETVAL=
fi
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
RETVAL=
esac
exit $RETVAL

root输入密码登录拒绝不成功可以:

在$SSHD $OPTIONS && success || failure这句话前面加一句:

OPTIONS="-f /etc/ssh/sshd_config"

配置如下:

        echo -n $"Starting $prog:"
OPTIONS="-f /opt/ssh7.9/etc/sshd_config" --同上目录/opt/openssh7.9.p1_2019/etc/sshd_config
 $SSHD $OPTIONS && success || failure RETVAL=$?

由于OpenSSH依赖的OpenSSL已不支持rsa1,所以我将启动脚本中生成rsa1秘钥的指令注释掉了。

接下来,关键的一步来了,我们要关闭旧的sshd服务,启动新的sshd服务。这个操作如果失败了,不会导致现有的ssh远程连接断开。所以我们可以先关闭旧的sshd程序,再启动新的sshd程序:

# service sshd.old stop
# service sshd start

如果新的sshd服务启动成功了,我们可以先简单测试下,比如,看看普通用户和root用户是否能正常通过ssh登录。如果没有没有问题,我们可以在测测其它的,比如scp、sftp是否正常等。当然,如果有条件的话,可以使用漏洞扫描工具扫一下,看看有没有什么我们没有注意到的地方。

最后,就可以删除掉旧sshd服务的启动脚本了,以免冲突:

# rm -f /etc/init.d/sshd.old

openssl和openssh的编译选项基本来说我也只是使用了必要的选项,我们编译出来的openssl和openssh软件在功能特性上只是尽可能地接近原有的,安全性和性能可能也是有差异。

复用了操作系统原有的sshd服务的配置文件和启动脚本,这可能无法充分利用新版本openssh的特性。openssl和openssh本来也是挺复杂的东西,一时半会可能也很难完全弄明白。

这种升级方式,应该会比强制升级openssl和openssh的方式好很多。

参考https://blog.51cto.com/techsnail/2138927,独指蜗牛 只做日常积累,不做商业用途,侵权即删。

linux升级openssh到7.9的更多相关文章

  1. linux升级openssh

    升级sshd到OpenSSH-6.7并删除老版本ssh 1)升级前准备 查看是否缺包 # rpm -qa | egrep "gcc|make|perl|pam|pam-devel" ...

  2. 升级openssh到高版本

    linux升级openssh到高版本 可以解决OpenSSH 安全漏洞(CVE-2018-15919)和SSH服务器类型和版本 如果是新服务器,需要安装对应命令vim 上传下载等命令 安装上传或者下载 ...

  3. linux升级安装openssh时出现依赖冲突

    通过如下方式下载到openssh安装包 https://www.cnblogs.com/qq931399960/p/11120429.html -rwxrwxrwx. root root Jul : ...

  4. redhat6.4升级openssh至6.7

    1:简介 最近浙江电信对线上服务器进行漏洞扫描,暴露出原有的openssh有漏洞,建议升级openssh版本: 2:操作环境 Red Hat Enterprise Linux Server relea ...

  5. 升级OpenSSH详细步骤

    由于系统扫描到OpenSSH版本太低,所以需要将其升级到高版本.网上搜罗数个文章,都多多少少有点疏漏.加上自己之前没升级过SSH,参考好几个文章查缺补漏才升级成功,着实废了不少劲儿.所以综合一下前辈们 ...

  6. CentOS 6.9 升级OpenSSH版本 关闭ssh服务后门

    最近用低版本的OpenSSH(5.9p1版本) 的漏洞给系统留了个后门 , 可以劫持root密码或者给root开启后门密码 : 利用Openssh后门 劫持root密码 如果公司还在用CentOS6的 ...

  7. CentOS 升级 openSSH

    openSSH作为linux远程连接工具,容易受到攻击,必须更新版本来解决,低版本有如下等漏洞: a. OpenSSH 远程代码执行漏洞(CVE-2016-10009) b.  OpenSSH aut ...

  8. redhat linux6.5升级openssh

    1.下载最新的openssh包 http://www.openssh.com/portable.html#http 2.升级openssh之前要先打开服务器telnet,通过telnet登录服务器,因 ...

  9. CentOS 升级 openSSH+ sh脚本自动运维

     升级前后对比 openSSH作为linux远程连接工具,容易受到攻击,必须更新版本来解决,低版本有如下等漏洞: OpenSSH 远程代码执行漏洞(CVE-2016-10009) OpenSSH au ...

随机推荐

  1. thinkphp5 部署注意事项

    配置tp5 需要修改设置 1. 通过yum安装的Apache,会默认安装在/etc/httpd因此配置文件也在相应的目录中 修改文件vim /etc/httpd/conf/httpd.confhttp ...

  2. H5转图片支持保存

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. Android 开发 values目录里定义数组、颜色、文本、尺寸xml配置文件并且获取数据 附录Android符号转码表

    以下xml都在res/values/文件夹下创建 创建String类型array: /app/src/main/res/values/array.xml <?xml version=" ...

  4. 【HQL】函数汇总

    背景 抽空整理一篇HQL函数及常用的小技巧 COALESCE COALESCE(T v1, T v2, -) 返回参数中的第一个非空值:如果所有值都为NULL,那么返回NULL

  5. 关于UILabel产生黑边的原因及去除方法

    原因:因为label自适应宽度得出来的labelsize.width是小数,才会有黑边 去除方法: 将labelsize.width转换成整数,如下: CGSize size = CGSizeMake ...

  6. 如何利用Git生成pitch和打pitch

    利用Git生成和应用patch  在程序员的日常开发与合作过程中,对于code的生成patch和打patch(应用patch)成为经常需要做的事情. 什么是patch?简单来讲,patch中存储的是你 ...

  7. 性能测试进阶指南——基础篇之磁盘IO

    本文旨在帮助测试人员对性能测试常用指标做一个简单的讲解,主要包括CPU.内存.磁盘和网络带宽等系统资源,本文仅仅局限于Linux系统,Windows Server系统暂不做考虑. 使用iostat分析 ...

  8. 富文本编辑器 kindeditor

    下载 在页面中添加JS代码,用于初始化kindeditor <script type="text/javascript"> var editor; KindEditor ...

  9. Python 学习笔记01篇

    编程基础很零碎 看了路飞学城的讲解视频,整体课程列表排列很清晰,每个视频都在十几分钟到二十几分钟之间,适合零碎化的的学习 第一章和第二章的前半部分可以较轻松地入门

  10. base64转码,解码方法

    function Base64() { // private property _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr ...