之前也设置过SSH登录,这次记下来吧。

生成公钥

使用ssh-keygen命令,例如执行ssh-keygen -t rsa即可

添加ssh key

在远程服务器的用户目录新建.ssh目录,新建authorized_keys文件,将本地上传的id_ras.pub里的内容添加到authorized_keys文件里。

这里需要注意.ssh和authorized_kesy权限,.ssh必须是700, 而authorized_keys文件只有文件拥有者有写权限。否则会提示Authentication refused: bad ownership or modes for file /home/dengsl/.ssh/authorized_keys错误。所以authorized_keys的权限设置必须为600, 640等等。

从阮一峰的博客里看到一条命令,但其实这条命令里存在错误,修改之后如下

1
ssh user@host 'mkdir -p .ssh && chmod 700 .ssh && touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub

如果已经存在.ssh目录,可以执行

1
ssh user@host 'chmod 700 .ssh && touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub

之后会提示输入密码,之后就可以不需要密码登录了。

禁止root用户登录

修改/etc/ssh/sshd_config文件,在#PermitRootLogin yes后面添加PermitRootLogin no即可。之后重启sshd服务service sshd restart使修改的配置生效

参考资料

联系作者

最近在DigitOcean买了VPS,又开始折腾主机。这次要记录下来。首先从新建用户开始。

新建用户

新增用户使用useradd命令,例如新增test用户,执行命令useradd test即可。新增用户后,要给用户设置密码,否则无法登录。

修改用户密码

设置密码使用passwd命令,例如给test用户设置密码,执行’passwd test’即可。

设置用户sudo不需要密码

每次安装软件都要切换到root用户比较麻烦,可以添加用户sudo时不需要密码。在/etc/sudoers文件里添加
test ALL=(ALL) NOPASSWD: ALL即可。

联系作者

最近服务时不时的会卡顿,不知道什么原因。下班之后突然想到速度慢,一般都出在数据库上。于是想到查看MySQL链接数,网上查到执行show processlist;即可。

在卡顿时,查询结果中发现以下可疑连接,如下

1
2
3
 Waiting for table level lock | UPDATE `sku` SET  `view_num` = `sku`.`view_num` + 1 WHER |         0 |             0 |         1 |

Waiting for table level lock | SELECT `sku`.`id`, `sku`.`name`, `sku`.`dosage_form`, `sku`.`specs`, `sku`.`factory`, `sku`.`categor | 0 | 0 | 1 |

在淘宝的MySQL资料MySQL 锁问题最佳实践里找到’table level lock’的原因,是因为MyISAM,引发table level lock wait。查看建表语句,果然是MyISAM引擎, 将它转成InnoDB即可解决问题。

上面使用show processlist命令显示不完全,可以加上full, 即执行show full processlist

参考Converting Tables from MyISAM to InnoDB, 执行ALTER TABLE table_name ENGINE=InnoDB;即可转换。

联系作者

在使用Supervisor监控Django项目时,在我的自己的站点设置里,没有加上stopasgroup=true选项,也就是关闭子进程,子进程也会退出。所以在公司的配置里,也没有加上这个选项。

后来发现,如果不加,在有请求时,gunicorn不会关闭子进程,此时子进程会变成孤儿进程,导致了资源占用率很高。在配置项里加上后,程序就正常了。所以建议都加上这个配置。

参考资料

联系作者

兼任运维后,爬虫这边的任务也要我处理了。发现之前的开发连日志都没有配置,纠错特别麻烦。查看Scrapy logging, 找到解决的办法,原来还是很简单的。

查看logging配置,发现只要配置LOG_FILE和LOG_FORMAT即可。

在settings中添加配置如下

1
2
LOG_FILE='logs/spider.log'
LOG_FORMAT= '%(levelname)s %(asctime)s [%(name)s:%(module)s:%(funcName)s:%(lineno)s] [%(exc_info)s] %(message)s'

其中LOG_FILE指定日志路径,而LOG_FORMAT指定日志格式。因为默认的LOG_FORMAT是没有输出日志的行数,所以这里增加了行数设置。

联系作者

某天,前端同事的Django项目无法启动,报you must set settings.allowed_hosts if debug is false错误,可是查看配置文件,明明设置debug=True, 不知为何。

找了好久,组长过来看了之后,发现是Cannot import name _uuid_generate_random错误,于是想到之前也遇到过这个问题,只是当时没有做笔记,所以印象不深。

按照cannot-import-name-uuid-generate-random-in-heroku-django, 升级Kombu到3.0.30,依然提示这个错误,
之后按照ImportError: cannot import name _uuid_generate_random的提示,升级celery, 执行pip install --upgrade celery,这次可以正常启动。

联系作者

最近测试服务器的数据库反复重启,产看日志, 提示

1
2
3
4
InnoDB: Log scan progressed past the checkpoint lsn 377750615222
InnoDB: The log sequence number in ibdata files does not match
InnoDB: the log sequence number in the ib_logfiles!
InnoDB: Database was not shut down normally!

之后无知的把ib_logfile1和ib_logfile2删掉,数据库依然反复重启。查看MySQL文件目录格式及存放位置才知道这两个文件还是有用的。

之后想到一个办法是重建数据库,也就是将SQL全部导出,之后再重新导入。在使用mysqldump导出数据时,老是提示mysqldump: Error 2013: Lost connection to MySQL server during query when dumping table, 原因还是数据库重启了。

参考官网[forcing-innodb-recovery]
(https://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html), 在/etc/my.cnf里配置innodb_force_recovery=3, 将数据库的SQL成功导出。

修改/etc/my.cnf里的datadir,在新的目录里重启MySQL, 之后使用mysql导入数据,数据库终于正常。

使用mysqldump导出test这个数据库的命令

1
mysqldump -h 127.0.0.1 -u root -p123456 test > test.sql

而使用mysql命令行工具导入

1
mysql -h 127.0.0.1 -u root -p123456 test < test.sql

联系作者

服务器上老是有人尝试破解root用户的SSH登录密码,要想办法解决。一个办法是屏蔽ip.

在/etc目录下存在hosts.allow和hosts.deny, 看名字就知道它们的意义。

  • hosts.allow指的是允许登录的ip
  • hosts.deny指的是不允许登录的ip
  • 两个文件配置后自动生效,不要重启什么服务,因为监控这两个文件的服务会自动加载两个文件里的内容
  • 添加了屏蔽ip后,在/var/log/secure里就可以看到效果
    如在/etc/hosts.allow里添加
    1
    sshd:101.71.255.*

则是允许101.71.255.*等ip地址SSH登录

在/etc/hosts.deny里添加

1
sshd:116.31.116.*

则是禁止116.31.116.*等ip地址SSH登录。

hosts.allow和hosts.deny里配置的地址如果出现重复,优先使用hosts.allow, 也就是允许该地址SSH登录。

在/etc/hosts.deny里还可以添加

1
sshd:all

此时,只有hosts.allow里配置的地址才允许SSH登录。在我看来, hosts.allow配置只有当hosts.deny配置了sshd:all才有意义。

其实解决暴力破解root用户密码的最好办法是禁止root用户SSH登录,而用普通用户登录,登录之后切换到root用户。

兼任运维以来,数据库出问题,文件系统出问题,也是运气差。目前来看,还有很多地方需要完善的,慢慢来吧。

联系作者

今天服务器上出现了无法写入viminfo文件 /root/.viminfo错误,网上有人说删除~/.viminf*.tmp即可,查看目录没有这些文件。

后来发现是文件都变成了只读,想到上午的时候ext3文件系统出了问题。在网上找到[http://www.ha97.com/5428.html], 执行df -lhT,知道是ext4文件系统
想执行fsck.ext4 -y /dev/vda1,但不允许。因为这是线上系统。

于是继续找,发现mount -o remount rw /, 当时提示mount: you must specify the filesystem type, 于是加上文件系统类型,执行mount -t ext4 -o remount rw /,之后提示
mount: cannot remount block device rw read-write, is write-protected
查看鸟哥的私房菜,使用鸟哥的命令
mount -o remount,rw,auto/, 没有反应。

于是求助UCloud的工作人员,他们建议重启服务器。等到晚上,重启服务器,系统就起不来了。于是只好找UCloud的工作人员。后来他们进入单用户模式,修复文件系统,重新mount之后,终于弄好了。

可是线上服务停机了一个多小时,因为是单点服务。看来得再加一台机器了。

参考资料

联系作者

当需要添加新的监控程序时,添加了配置后,需要重新加载,这样才能监控起来。此时supervisorctl update命令就派上用场了。

执行supervisorctl update命令后,添加的配置会加载到Supervisor里,这样就可以用Supervisor监控程序了。

发现program配置里有directory这个选项,目的是在启动程序时,让程序进入的目录。例如在使用gunicorn启动Django项目时,如果wsgi指定的路径使用/隔开,则会报importerror import by filename is not supported, 配置directory为wsgi所在的目录,问题就得到解决。

联系作者