ubuntu 16.04编译安装gqrx-v2.11.2

$ sudo apt-get install qt5-qmake

$ sudo apt-get install qtbase5-dev

$ sudo apt-get install pkg-config

$ sudo apt-get install libqt5svg5-dev

$ export QT_SELECT=qt5

$ cd ~

$ git clone https://github.com/csete/gqrx.git

$ cd gqrx

$ git checkout v2.11.2

$ mkdir build

$ cd build

$ qmake ../gqrx.pro

$ make

如果代码下载困难,可以从本站下载一份拷贝。 gqrx

参考链接


ubuntu 16.04编译安装HackRF One软件及固件hackrf-v2018.01.1

ubuntu 16.04编译安装HackRF One软件及固件hackrf-v2018.01.1

$ cd ~

$ git clone https://github.com/mossmann/hackrf.git

$ cd hackrf

$ git checkout v2018.01.1 

#编译工具
$ cd host

$ mkdir build

$ cd build

$ cmake .. -DINSTALL_UDEV_RULES=ON

$ make

$ sudo make install

#编译固件
$ sudo apt-get install gcc-arm-none-eabi

$ cd ~

$ cd hackrf

$ git submodule init

$ cd firmware

$ cd libopencm3

$ make 

$ cd ..

$ mkdir build 

$ cd build

$ cmake .. -DBOARD=HACKRF_ONE

$ make


#升级固件
$ hackrf_spiflash -w ./hackrf_usb/hackrf_usb.bin

如果代码下载困难,可以从这里下载一份代码拷贝 hackrf

参考链接


ubuntu 16.04系统wordpress-4.9.4修改表引擎报告错误“Invalid default value for 'comment_date'”

最近在捣鼓wordpress主从同步的时候(ubuntu 16.04配置MySQL主从同步),需要把wp_comments的数据库引擎从MyISAM切换到INNODBMyISAM不支持主从同步)。

在执行

$ mysql -u root -p -e "use wordpress; ALTER TABLE wp_comments ENGINE=INNODB;"

的时候报告错误:

Invalid default value for 'comment_date'

原因出在类似这样的建表语句

DROP TABLE IF EXISTS `wp_comments`;
CREATE TABLE `wp_comments`  (
  `comment_ID` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `comment_post_ID` bigint(20) UNSIGNED NOT NULL DEFAULT 0,
  `comment_author` tinytext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL,
  `comment_author_email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
  `comment_author_url` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
  `comment_author_IP` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
  `comment_date` datetime(0) NOT NULL DEFAULT '0000-00-00 00:00:00',
  `comment_date_gmt` datetime(0) NOT NULL DEFAULT '0000-00-00 00:00:00',
  `comment_content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL,
  `comment_karma` int(11) NOT NULL DEFAULT 0,
  `comment_approved` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '1',
  `comment_agent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
  `comment_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
  `comment_parent` bigint(20) UNSIGNED NOT NULL DEFAULT 0,
  `user_id` bigint(20) UNSIGNED NOT NULL DEFAULT 0,
  PRIMARY KEY (`comment_ID`) USING BTREE,
  INDEX `comment_post_ID`(`comment_post_ID`) USING BTREE,
  INDEX `comment_approved_date_gmt`(`comment_approved`, `comment_date_gmt`) USING BTREE,
  INDEX `comment_date_gmt`(`comment_date_gmt`) USING BTREE,
  INDEX `comment_parent`(`comment_parent`) USING BTREE,
  INDEX `comment_author_email`(`comment_author_email`(10)) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 35 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_520_ci ROW_FORMAT = Dynamic;

这种报错多是mysql升级到5.7而引起的默认值不兼容的问题。看看你的字段名是什么,我的是时间字段,类型是datetime。想到可能是类型的默认值被限制了,查看sql_mode。果然:NO_ZERO_IN_DATE,NO_ZERO_DATE这两个参数限制时间不能为0

可以使用如下语句查看建表命令:

$ mysql -u root -p -e "use wordpress;show create table wp_comments\G;“

注意上面的

`comment_date` datetime(0) NOT NULL DEFAULT '0000-00-00 00:00:00', 
`comment_date_gmt` datetime(0) NOT NULL DEFAULT '0000-00-00 00:00:00',

这两句受到NO_ZERO_IN_DATE,NO_ZERO_DATE的影响。

查看 sql_mode

mysql> show variables like 'sql_mode';
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

临时修改:

mysql> set session
 -> sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql>

永久修改:

修改配置文件

$ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

[mysqld]下面添加如下列:

sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

参考链接


导入数据库时报错1067 – Invalid default value for ‘字段名’

ubuntu 16.04删除被denyhosts阻止的IP地址

参照 ubuntu 16.04防止SSH暴力登录攻击 安装denyhosts之后,由于某些莫名的操作导致自己的一个登录地址被加入了阻止列表,尝试很多次之后,都没有办法恢复。于是找到如下脚本来进行删除操作:

#!/bin/bash

IP=$1
if [ -n "$IP" ];then
    if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]];then
        service denyhosts stop
        sed -i "/$IP/d" /etc/hosts.deny
        sed -i "/$IP/d" /var/lib/denyhosts/hosts-valid
        sed -i "/$IP/d" /var/lib/denyhosts/users-hosts
        sed -i "/$IP/d" /var/lib/denyhosts/hosts
        sed -i "/$IP/d" /var/lib/denyhosts/hosts-root
        sed -i "/$IP/d" /var/lib/denyhosts/hosts-restricted
        iptables -D INPUT -s $IP -j DROP 
        echo $IP remove from Denyhosts
        service denyhosts start
    else
        echo "This is not IP"
    fi
else
    echo "IP is empty"
fi

生成脚本后,如下方式执行:

$ sudo bash denyhosts_unban.sh 42.120.74.106

参考链接


ubuntu 16.04配置MySQL主从同步

准备工作

1.主从数据库版本最好一致

2.主从数据库内数据保持一致

主数据库:121.199.27.227 /ubuntu 16.04 MySQL 5.7.21 (阿里云

从数据库:182.254.149.39 /ubuntu 16.04 MySQL 5.7.21 (腾讯云

防火墙配置

配置主服务器只允许特定IP访问数据库的端口,避免不必要的攻击。

主库防火墙配置
# iptables -A INPUT -p tcp -s slave_ip --dport 3306 -j ACCEPT

#删除可能已经存在的配置,避免出现多条重复记录
$ sudo iptables -D INPUT -p tcp -s 182.254.149.39 --dport 3306 -j ACCEPT 
$ sudo iptables -D INPUT -p tcp -s 127.0.0.1 --dport 3306 -j ACCEPT 
$ sudo iptables -D INPUT -p tcp --dport 3306 -j DROP 
$ sudo iptables -D INPUT -p udp --dport 3306 -j DROP 
$ sudo iptables -D INPUT -p sctp --dport 3306 -j DROP

#增加配置,只允许特定地址访问数据库端口
$ sudo iptables -A INPUT -p tcp -s 182.254.149.39 --dport 3306 -j ACCEPT
$ sudo iptables -A INPUT -p tcp -s 127.0.0.1 --dport 3306 -j ACCEPT
$ sudo iptables -A INPUT -p tcp --dport 3306 -j DROP
$ sudo iptables -A INPUT -p udp --dport 3306 -j DROP
$ sudo iptables -A INPUT -p sctp --dport 3306 -j DROP

$ sudo iptables -L -n -v

#保存配置
$ sudo apt-get install iptables-persistent

#注意,iptables-persistent 与 ufw 冲突, 
#现象就是系统重启后执行 sudo ufw status 显示 inactive,
#但是sudo systemctrl ufw status 或sudo service ufw status 显示服务正常,
#实际上ufw并没有正常工作。
#如果两者同时安装,需要参考 https://www.mobibrw.com?p=29330 进行配置

$ sudo netfilter-persistent save

#配置被保存到/etc/iptables/rules.v4 /etc/iptables/rules.v6这两个文件下面,
#最好确认一下实际保存的内容,尤其是安装了denyhosts等其他安全软件的情况下,
#可能会记录了多余的规则,需要手工删除
从库防火墙配置
# iptables -A OUTPUT -p tcp -d master_ip --dport 3306 -j ACCEPT

#删除可能已经存在的配置,避免出现多条重复记录
$ sudo iptables -D OUTPUT -p tcp -d 121.199.27.227 --dport 3306 -j ACCEPT

#增加配置
$ sudo iptables -A OUTPUT -p tcp -d 121.199.27.227 --dport 3306 -j ACCEPT

$ sudo iptables -L -n

#保存配置
$ sudo apt-get install iptables-persistent

#注意,iptables-persistent 与 ufw 冲突, 
#现象就是系统重启后执行 sudo ufw status 显示 inactive,
#但是sudo systemctrl ufw status 或sudo service ufw status 显示服务正常,
#实际上ufw并没有正常工作。
#如果两者同时安装,需要参考 https://www.mobibrw.com?p=29330 进行配置

$ sudo netfilter-persistent save

#配置被保存到/etc/iptables/rules.v4 /etc/iptables/rules.v6这两个文件下面,
#最好确认一下实际保存的内容,尤其是安装了denyhosts等其他安全软件的情况下,
#可能会记录了多余的规则,需要手工删除

主数据库master配置

1.修改mysql配置

$ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

在[mysqld]部分进行如下修改:

[mysqld]
#开启二进制日志,默认是注释掉的,我们去掉注释
log-bin = /var/log/mysql/mysql-bin.log 

#设置server-id
server-id = 1 

#默认是127.0.0.1,此处我们设置为任意地址,放开远程访问,这么操作之前一定要确保防火墙配置正确,否则会产生安全风险
bind-address = 0.0.0.0 

#如果数据库是从5.7版本之前升级的,并且是wordpress那么会遇到无法更改数据库的情况,
#NO_ZERO_IN_DATE,NO_ZERO_DATE这两个参数限制的,我们需要去掉这个限制,原因在于
#wordpress创建的表中存在
#`comment_date` datetime(0) NOT NULL DEFAULT '0000-00-00 00:00:00',
#这样的定义是没办法进行后续的操作的,因此我们需要重新定义sql_mode来解除这个限制
sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

2.修改需要同步的表的引擎为INNODB,只有INNODB支持主从,MyISAM不支持

# 此处以wordpress为例,默认情况下wordpress中的wp_options表为MyISAM引擎,
# 这会导致数据同步失败,可能出现的错误信息如下:
# Last_Errno: 1032
# Last_Error: Could not execute Delete_rows event on table wordpress.wp_options; Can't find record in 'wp_options', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000007, end_log_pos 3678486
# 使用“show create table wp_options\G;”查看表的引擎信息
# 单个表修改的命令如下
#mysql -u root -p -e "use wordpress; ALTER TABLE wp_options ENGINE=INNODB;"

#整个数据库修改的命令如下,下面的语句只是生成执行语句,具体执行,还需要把结果拷贝出来执行
$ mysql -u root -p -e "USE wordpress; SET @DATABASE_NAME = 'wordpress'; SELECT GROUP_CONCAT(CONCAT( 'ALTER TABLE ' ,TABLE_NAME ,' ENGINE=InnoDB; ') SEPARATOR '' ) FROM information_schema.TABLES AS t WHERE TABLE_SCHEMA = @DATABASE_NAME AND TABLE_TYPE = 'BASE TABLE' AND ENGINE = 'MyISAM';"

#我这边的例子如下
$ mysql -u root -p -e "USE wordpress; ALTER TABLE wp_IPBLC_blacklist ENGINE=InnoDB; ALTER TABLE wp_IPBLC_login_failed ENGINE=InnoDB; ALTER TABLE wp_IPBLC_usernames ENGINE=InnoDB; ALTER TABLE wp_commentmeta ENGINE=InnoDB; ALTER TABLE wp_comments ENGINE=InnoDB; ALTER TABLE wp_links ENGINE=InnoDB; ALTER TABLE wp_options ENGINE=InnoDB; ALTER TABLE wp_postmeta ENGINE=InnoDB; ALTER TABLE wp_posts ENGINE=InnoDB; ALTER TABLE wp_term_relationships ENGINE=InnoDB; ALTER TABLE wp_term_taxonomy ENGINE=InnoDB; ALTER TABLE wp_terms ENGINE=InnoDB; ALTER TABLE wp_usermeta ENGINE=InnoDB; ALTER TABLE wp_users ENGINE=InnoDB;"

3.重启mysql,创建用于同步的用户账号

创建用户并授权:用户:repl 密码:slavepass

$ sudo service mysql restart

$ mysql -u root -p -e "CREATE USER 'repl'@'182.254.149.39' IDENTIFIED BY 'slavepass';" #创建用户

$ mysql -u root -p -e "GRANT REPLICATION SLAVE ON *.* TO 'repl'@'182.254.149.39';" #分配权限

$ mysql -u root -p -e "flush privileges;"  #刷新权限

$ mysql -u root -p -e "SELECT User, Host FROM mysql.user;"  #查看用户

4.查看master状态,记录二进制文件名(mysql-bin.000001)和位置(333802):

# 阻止数据库记录写入,避免后期我们备份数据库的时候数据发生变动
# 该命令对于普通账号的只读模式,root 账号无效,因此访问数据库的账号
# 尽量不要使用root账号,如果是root 账号,只能暂时停止所有访问数据库的服务了
$ mysql -u root -p -e "set global read_only=1;"  

$ mysql -u root -p -e "SHOW MASTER STATUS;"
Enter password: 
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |   333802 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

5.主库备份,为从库的第一次数据同步准备数据

使用如下脚本产生数据库备份文件

#此处以备份wordpress数据库为例子

datadump=`which mysqldump`

mysqluser="root"

userpass="password" 

wordpressdb="wordpress"

backupwordpress_sql=$wordpressdb.`date +%Y%m%d`.sql

# 注意,如果是MySQL 8.x那么 --master-data 需要修改成 --source-data 否则在备份的第一句会出现如下警告 
#“WARNING: --master-data is deprecated and will be removed in a future version. Use --source-data instead.”

ver=`mysqldump -V | sed -nre 's/^[^0-9]*(([0-9]+\.)*[0-9]+).*/\1/p'`

args='--master-data'

if [ "${ver}"\>="8.0.0" ]; then
  args='--source-data'
fi

if $datadump $args --single-transaction -u $mysqluser --password=$userpass -h localhost --opt $wordpressdb > $backupwordpress_sql 2>&1
then
  echo " backup $wordpressdb success"
else
  echo " backup $wordpressdb error"
  exit 1
fi

#检验文件尾部是否存在 “-- Dump completed on”,如果存在不存在,则说明备份出错了。
if [ 0 -eq "$(sed '/^$/!h;$!d;g' $backupwordpress_sql | grep -c "Dump completed on")" ]; 
then
  echo " backup $wordpressdb error"
  exit 1	
else
  echo " backup $wordpressdb success"
fi

执行脚本,确保最后输出备份成功

$ cd ~

$ sudo bash backup_wordpress.sh

# 取消普通账号的只读模式
$ mysql -u root -p -e "set global read_only=0;"

从服务器slave配置

1.修改mysql配置

$ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

修改server-id,每个数据库的server-id要求是唯一的,不能相互冲突

[mysqld]
#设置server-id,必须唯一
server-id = 2

# 根据业务需要配置数据库是否只读
#read_only = on
#super_read_only = on
#tx_read_only = on

#日志也最好打开
log_bin                 = /var/log/mysql/mysql-bin.log

#如果日志开启了,最好把日志格式设置为row格式,这样如果主从数据不一致,可以尝试mysql flashback功能
binlog-format    = row 

#如果数据库是从5.7版本之前升级的,并且是wordpress那么会遇到无法更改数据库的情况,
#NO_ZERO_IN_DATE,NO_ZERO_DATE这两个参数限制的,我们需要去掉这个限制,原因在于
#wordpress创建的表中存在
#`comment_date` datetime(0) NOT NULL DEFAULT '0000-00-00 00:00:00',
#这样的定义是没办法进行后续的操作的,因此我们需要重新定义sql_mode来解除这个限制
sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

2.首次还原数据库:

#停止可能访问数据库的应用
$ sudo service apache2 stop

$ sudo service php7.0-fpm stop

$ sudo service mysql restart

# 确保无应用访问数据库的情况下,记录主库日志位置,并执行备份脚本
 mysql -u root -p -e "SHOW MASTER STATUS;"
Enter password: 
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |   333802 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

$ sudo bash backup_wordpress.sh

# 此处已经可以启动刚刚关闭的服务了
$ sudo service php7.0-fpm start

$ sudo service apache2 start

$ scp -P 22 -r root@121.199.27.227:~/wordpress.*.sql ./

#删除可能存在的一行警告信息,这行警告信息可能导致我们无法恢复数据
$ sed -i "/^mysqldump: \[Warning\] Using a password on the command line interface can be insecure\./d" wordpress.*.sql

$ mysql -u root -p -e "stop slave;"

$ mysql -u root -p -e "drop database wordpress;"

$ mysql -u root -p -e "create database wordpress;"

$ mysql -u root -p wordpress < wordpress.*.sql

还原完成后,把数据库设置成只读模式,如果从库可写会出现冲突导致同步失败

$ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

添加如下语句:

[mysqld]
#数据库只读 
#read_only = on 

super_read_only = on 

#tx_read_only = on

3.重启mysql,执行同步SQL语句(需要主服务器主机名,登陆凭据,二进制文件的名称和位置):

$ sudo service mysql restart

#只读模式
$ mysql -u root -p -e "set global read_only=1;"

#最好使用如下命令获得主库的起始位置
$ grep 'CHANGE MASTER TO MASTER_LOG_FILE'  wordpress.*.sql | more

$ mysql -u root -p -e "CHANGE MASTER TO MASTER_HOST='121.199.27.227', MASTER_USER='repl', MASTER_PASSWORD='slavepass', MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=333802;"

4.启动slave同步进程:

$ mysql -u root -p -e "start slave;"

5.查看slave状态:

$ mysql -u root -p -e "show slave status\G;"
Enter password:
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 121.199.27.227
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 9448236
               Relay_Log_File: VM-114-251-ubuntu-relay-bin.000002
                Relay_Log_Pos: 17780
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
        ...

当Slave_IO_Running和Slave_SQL_Running都为YES的时候就表示主从同步设置成功了。接下来就可以进行一些验证了,比如在主master数据库的test数据库的一张表中插入一条数据,在slave的test库的相同数据表中查看是否有新增的数据即可验证主从复制功能是否有效,还可以关闭slave(mysql>stop slave;),然后再修改master,看slave是否也相应修改(停止slave后,master的修改不会同步到slave),就可以完成主从复制功能的验证了。

还可以用到的其他相关参数:

master开启二进制日志后默认记录所有库所有表的操作,可以通过配置来指定只记录指定的数据库甚至指定的表的操作,具体在mysql配置文件的[mysqld]可添加修改如下选项:

# 不同步哪些数据库  
binlog-ignore-db = mysql  
binlog-ignore-db = test  
binlog-ignore-db = information_schema  
  
# 只同步哪些数据库,除此之外,其他不同步  
binlog-do-db = game

如之前查看master状态时就可以看到只记录了test库,忽略了manual和mysql库。

注意,偶尔在系统升级的时候,从库可能会丢失同步状态配置。这时候,我们需要重新同步,此时我们从从设备`/var/lib/mysql/master.info`中找到被中断的同步点。

里面的内容一般如下:

25
mysql-bin.000582
4765083
121.199.27.227
xxxx
xxxx
3306
60
1
/etc/mysql/ssl/ca.pem
/etc/mysql/ssl
/etc/mysql/ssl/client-cert.pem

/etc/mysql/ssl/client-key.pem
0
30.000

0
0b674082-f01d-11e9-8f8c-00163e0a4ffe
86400


0

注意`mysql-bin.000582`下面的`4765083`就是同步位置,在恢复的时候,就是这两个关键数据。

参考链接


ubuntu 16.04防止SSH暴力登录攻击

最近观察服务器的认证日志,发现有些国外的IP地址,多次尝试破解服务器的密码进行登录。于是希望能将多次尝试 `SSH` 登录失败的IP阻止掉。

查看日志文件:

$ sudo cat /var/log/auth.log

看到很多如下的日志:

Failed password for root from 123.15.36.218 port 51252 ssh2
reverse mapping checking getaddrinfo for pc0.zz.ha.cn [218.28.79.228] failed – POSSIBLE BREAK-IN ATTEMPT!
Invalid user akkermans from 218.28.79.228
pam_unix(sshd:auth): check pass; user unknown
pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=218.28.79.228

来统计一下有多少人在暴力破解 `root` 密码

$ sudo grep "Failed password for root" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nr | more

     16 212.237.47.236
      5 42.120.74.106
      4 ;
      1 80.211.140.131

如果已经禁用了root登录,则看一下暴力猜用户名的统计信息

$ sudo grep "Failed password for invalid user" /var/log/auth.log | awk '{print $13}' | sort | uniq -c | sort -nr | more

    129 212.237.47.236
      3 ;
      1 80.211.140.131

某个人尝试了 `129` 次。为了防范于未然,我们可以做些配置,让服务器更加安全。

下面的三个方法,可以完全使用,也可以部分使用。一般建议使用其中的第一条跟第三条。

1. 修改 `SSH` 端口,禁止`root` 登陆

修改/etc/ssh/sshd_config文件

$ sudo vim /etc/ssh/sshd_config

Port 4484 #一个别人猜不到的端口号
PermitRootLogin no

$ sudo service sshd restart

2. 禁用密码登陆,使用 `RSA` 私钥登录

如果服务器只允许使用私钥登录的,但是如果想在别的电脑上临时SSH上来,又没带私钥文件的情况下,就很麻烦。所以还是保留密码验证登录。不管怎样,这一条还是先列出来

# 在客户端生成密钥
$ ssh-keygen -t rsa

# 把公钥拷贝至服务器
$ ssh-copy-id -i .ssh/id_rsa.pub server

# 也可以手动将.shh/id_rsa.pub拷贝至服务器用户目录的.ssh中,记得修改访问权限
# $ scp .shh/id_rsa.pub server:~/.ssh

# 在服务器中
$ cd ./.ssh/

$ mv id_rsa.pub authorized_keys

$ chmod 400 authorized_keys

$ vim /etc/ssh/sshd_config

RSAAuthentication yes #RSA认证
PubkeyAuthentication yes #开启公钥验证
AuthorizedKeysFile .ssh/authorized_keys #验证文件路径
PasswordAuthentication no #禁止密码认证
PermitEmptyPasswords no #禁止空密码
UsePAM no #禁用PAM


# 最后保存,重启
$ sudo service sshd restart

3. 安装 `denyhosts`

`denyhosts` 是 `Python` 语言写的一个程序,它会分析 `sshd` 的日志文件,当发现重复的失败登录时就会记录 `IP` 到 `/etc/hosts.deny` 文件,从而达到自动屏 `IP` 的功能。现今 `denyhosts` 在各个发行版软件仓库里都有。

注意在 `ubuntu 16.04` 系统上,如果通过远程的 `SSH` 登录到服务器上执行安装命令的话,会由于默认情况下 `RESET_ON_SUCCESS = yes #如果一个ip登陆成功后,失败的登陆计数是否重置为0` 这部分,默认情况下是关闭的。而如果恰好我们又出现自己输入的错误密码错误累计次数超过 `5` 次的情况(即使后面有成功登录的记录也不行),会导致我们自己当前登录的地址也被阻止的情况。这种情况发生之后,会导致我们自己无法控制服务器(这个阻塞是在 `iptables` 层阻塞的,如果要恢复,在 `iptables` 中删除已经添加的记录才可以)。解决办法就是换一个新的 `IP` 地址登录服务器,然后修改 `RESET_ON_SUCCESS` 这个参数,并重启 `denyhosts` 服务。如果是阿里云或者腾讯云的服务器,可以尝试从他们网站上提供的网页版本的 `Shell` 进行操作。

对于 `ubuntu 16.04` 系统,建议使用如下方式进行安装:

#创建执行脚本
$ touch ~/install.sh

#创建执行安装命令,整个过程不中断连续执行,如果不使用脚本,执行到这里,可能SSH就已经被阻断了
#安装完成后,denyhosts的服务就已经开始运行了,此时可能已经设置了iptables了
$ echo "sudo apt-get install denyhosts" >> ~/install.sh 

#创建修改配置文件的命令
$ echo "sudo sed -i 's/^#RESET_ON_SUCCESS/RESET_ON_SUCCESS/g' /etc/denyhosts.conf" >> ~/install.sh

#创建重启服务的命令
$ echo "sudo service denyhosts restart" >> ~/install.sh

#执行我们刚刚的安装脚本
$ sudo bash ~/install.sh

默认配置就能很好的工作,如要个性化设置可以修改 `/etc/denyhosts.conf`

$ sudo vim /etc/denyhosts.conf

SECURE_LOG = /var/log/auth.log #ssh 日志文件,它是根据这个文件来判断的。
HOSTS_DENY = /etc/hosts.deny #控制用户登陆的文件
PURGE_DENY = #过多久后清除已经禁止的,空表示永远不解禁
BLOCK_SERVICE = sshd #禁止的服务名,如还要添加其他服务,只需添加逗号跟上相应的服务即可
DENY_THRESHOLD_INVALID = 5 #允许无效用户失败的次数
DENY_THRESHOLD_VALID = 10 #允许普通用户登陆失败的次数
DENY_THRESHOLD_ROOT = 1 #允许root登陆失败的次数
DENY_THRESHOLD_RESTRICTED = 1
WORK_DIR = /var/lib/denyhosts #运行目录
SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS=YES
HOSTNAME_LOOKUP=YES #是否进行域名反解析
LOCK_FILE = /var/run/denyhosts.pid #程序的进程ID
ADMIN_EMAIL = root@localhost #管理员邮件地址,它会给管理员发邮件
SMTP_HOST = localhost
SMTP_PORT = 25
SMTP_FROM = DenyHosts <nobody@localhost>
SMTP_SUBJECT = DenyHosts Report
AGE_RESET_VALID=5d #用户的登录失败计数会在多久以后重置为0,(h表示小时,d表示天,m表示月,w表示周,y表示年)
AGE_RESET_ROOT=25d
AGE_RESET_RESTRICTED=25d
AGE_RESET_INVALID=10d
RESET_ON_SUCCESS = yes #如果一个ip登陆成功后,失败的登陆计数是否重置为0
DAEMON_LOG = /var/log/denyhosts #自己的日志文件
DAEMON_SLEEP = 30s #当以后台方式运行时,每读一次日志文件的时间间隔。
DAEMON_PURGE = 1h #当以后台方式运行时,清除机制在 HOSTS_DENY 中终止旧条目的时间间隔,这个会影响PURGE_DENY的间隔。

查看 `/etc/hosts.deny` 发现里面已经有 `3` 条记录。

$ sudo cat /etc/hosts.deny | wc -l
3

目前 `ubuntu 16.04` 系统源里的 `denyhosts` 存在一个 `BUG` ,就是系统重启之后,`iptables` 中的拦截设置没有恢复。具体的讨论以及描述,参考Iptables not persistent,代码应该已经增加了,目前还没合并到主分支。

对于 `ubuntu 20.04` 系统,默认源已经不包含 `denyhosts` ,需要使用 `Fail2ban` 替代。参考 How to Install and Configure Fail2ban on Ubuntu 20.04

参考链接


int在32/64位系统中的字节数

 

64-bit data models
Data model short (integer) int long (integer) long long pointers,
size_t
Sample operating systems
SILP64 64 64 64 64 64 Classic UNICOS[41] (versus UNICOS/mp, etc.)
ILP64 16 64 64 64 64 HAL Computer Systems port of Solaris to the SPARC64
LLP64,
IL32P64
16 32 32 64 64 Microsoft Windows (x86-64 and IA-64) using Visual C++; and MinGW
LP64,
I32LP64
16 32 64 64 64 Most Unix and Unix-like systems, e.g., Solaris, Linux, BSD, macOS. Windows when using Cygwin; z/OS

参考链接


32位和64位系统区别及int字节数
64-Bit Programming Models: Why LP64?
64-bit computing
What decides the sizeof an integer?

ubuntu 16.04如何修改gnome-terminal标题栏内容

最近在使用ubuntu 16.04上使用多个gnome-terminal执行脚本的时候,标题栏上显示的都是"终端"这两个字,导致无法区分是哪个脚本的控制台输出。

我们是使用如下的方式要求gnome-terminal启动并执行我们指定的Shell

$ gnome-terminal -e "run.sh"

为了修改标题,可以在我们需要执行的run.sh中增加如下命令:

echo -ne "\033]0;SOME TITLE HERE\007"

具体的标题内容请替换其中的"SOME TITLE HERE"为需要的内容即可。

参考链接


How to change Gnome-Terminal title?

ubuntu 16.04系统LimeSDR V1.4使用OpenAirInterface搭建LTE实验环境

操作系统调整

参考 ubuntu 16.04低延迟内核 安装低延时内核CPU调整为最大性能模式,并且不允许降低频率。

$ sudo apt-get install cpufrequtils

$ sudo touch /etc/default/cpufrequtils

$ sudo sed -i "/GOVERNOR.*/d" /etc/default/cpufrequtils

$ test -s /etc/default/cpufrequtils && sudo sed -i '$a\GOVERNOR=\"performance\"' /etc/default/cpufrequtils || echo "GOVERNOR=\"performance\"" | sudo tee /etc/default/cpufrequtils

$ sudo update-rc.d ondemand disable

$ sudo reboot

安装依赖包

$ sudo apt-get install cmake g++ libpython-dev python-numpy swig git libsqlite3-dev libi2c-dev libusb-1.0-0-dev libwxgtk3.0-dev freeglut3-dev

编译安装SoapySDR

$ cd ~

$ git clone https://github.com/pothosware/SoapySDR.git

$ cd SoapySDR

$ git pull origin master

$ mkdir build && cd build

$ cmake ..

$ make -j4

$ sudo make install

$ sudo ldconfig

编译安装LimeSDR

$ cd ~ 

$ git clone https://github.com/myriadrf/LimeSuite.git

$ cd LimeSuite

#目前的测试发现,超过这个版本的代码无法正常的发出信号,
#也就是手机搜索不到我们创建好的基站,
#反复研究,确认是“Commit 9883bb97 by ignasj, 2017-06-30 下午04:20” 
#对于“lms7_device.cpp”的修改导致的问题,原因为天线发射增益设置不正确
#解决方法参考 https://www.mobibrw.com/?p=11957
#截止目前2018.09.03版本的代码貌似已经修正这个问题了,应该已经可以正常使用了。
#测试来说,还是使用这个版本吧

$ git checkout v17.06.0

# 不可删除build目录,清理build目录后要还原被误删除的文件,
# 原因在于build目录下存在mcu程序,默认应用启动后从这个目录提取mcu程序刷新到设备

$ mkdir build ; cd build

# cmake -DCMAKE_BUILD_TYPE=Debug ..
$ cmake ..

$ make -j4

$ sudo make install

$ sudo ldconfig

$ cd ../udev-rules/

$ sudo bash install.sh

# Download board firmware
$ sudo LimeUtil --update

#固件下载地址 http://downloads.myriadrf.org/project/limesuite/
#如果上述的固件无法下载,可以从此处下载一份拷贝
#http://www.mobibrw.com/wp-content/uploads/2018/03/17.06-LimeUtils-fpga-fw.zip

编译安装USRP驱动

$ sudo apt-get install libboost-all-dev libusb-1.0-0-dev python-mako doxygen python-docutils python-requests cmake build-essential

$ cd ~

$ git clone git://github.com/EttusResearch/uhd.git

$ cd uhd; mkdir host/build; cd host/build

$ cmake -DCMAKE_INSTALL_PREFIX=/usr ..

$ make -j4

$ sudo make install

$ sudo ldconfig

#下面脚本的作用是到http://files.ettus.com/binaries/images/下载最新的镜像文件,并解压缩到 /usr/share/uhd/images目录下

$ sudo /usr/lib/uhd/utils/uhd_images_downloader.py

#如果上面的镜像下载失败,可以尝试执行如下命令从本站下载
# cd ~ ; wget http://www.mobibrw.com/wp-content/uploads/2018/03/uhd-images_003.010.003.000-release.zip
# sudo unzip uhd-images_003.010.003.000-release.zip -d /user

下载并解压缩需要的补丁,点击此处下载

$ cd ~

# 原始补丁地址 http://open-cells.com/d5138782a8739209ec5760865b1e53b0/opencells-mods-20170710.tgz

$ wget http://www.mobibrw.com/wp-content/uploads/2018/03/opencells-mods-20170710.tgz

$ tar xf opencells-mods-20170710.tgz

下载并编译eNB

$ cd ~

$ git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git

$ cd openairinterface5g

$ git checkout develop

#目前的补丁程序只在这个版本上是有效的,后续版本会补丁失败
$ git checkout 08b8b3142df16831396a5283a015564ff56bf91c -b ubuntu16

#应用补丁
$ git apply ../opencells-mods/eNB.patch

#对于国内的用户来说,国外的几个代码地址需要修改一下,否则会出现无法下载或者下载非常慢的情况
$ sed -i "s/git clone https:\/\/gist.github.com\/2190472.git \/opt\/ssh/wget https:\/\/www.mobibrw.com\/wp-content\/uploads\/2018\/03\/ssh.tar.gz \&\& sudo tar -zxvf ssh.tar.gz -C \/opt/g" cmake_targets/tools/build_helper

$ sed -i "s/git clone https:\/\/gitlab.eurecom.fr\/oai\/asn1c.git \/tmp\/asn1c/wget https:\/\/www.mobibrw.com\/wp-content\/uploads\/2018\/03\/asn1c.tar.gz \&\& tar -zxvf asn1c.tar.gz -C \/tmp/g" cmake_targets/tools/build_helper

$ sed -i "s/https:\/\/pypi.python.org\/packages\/18\/fa\/dd13d4910aea339c0bb87d2b3838d8fd923c11869b1f6e741dbd0ff3bc00\/netifaces-0.10.4.tar.gz/https:\/\/www.mobibrw.com\/wp-content\/uploads\/2018\/03\/netifaces-0.10.4.tar.gz/g" cmake_targets/tools/build_helper

$ sed -i "s/https:\/\/github.com\/google\/protobuf\/releases\/download\/v2.6.1\/protobuf-2.6.1.tar.gz/https:\/\/www.mobibrw.com\/wp-content\/uploads\/2018\/03\/protobuf-2.6.1.tar.gz/g" cmake_targets/tools/build_helper

$ sed -i "s/git clone https:\/\/github.com\/protobuf-c\/protobuf-c.git/wget https:\/\/www.mobibrw.com\/wp-content\/uploads\/2018\/03\/protobuf-c.tar.gz \&\& tar -zxvf protobuf-c.tar.gz/g" cmake_targets/tools/build_helper

$ sed -i "s/http:\/\/mirrors.dotsrc.org\/gcrypt\/gnutls\/v3.1\/gnutls-3.1.23.tar.xz/https:\/\/www.mobibrw.com\/wp-content\/uploads\/2018\/03\/gnutls-3.1.23.tar.xz/g" cmake_targets/tools/build_helper

$ sed -i "s/https:\/\/ftp.gnu.org\/gnu\/nettle\/nettle-2.5.tar.gz/https:\/\/www.mobibrw.com\/wp-content\/uploads\/2018\/03\/nettle-2.5.tar.gz/g" cmake_targets/tools/build_helper 

#修正兼容问题,更高版本的protobuf-c跟我们上面安装的版本不匹配,会导致编译错误
$ sed -i "s/cd protobuf-c/cd protobuf-c \&\& git checkout 2a46af42784abf86804d536f6e0122d47cfeea45/g" cmake_targets/tools/build_helper

#执行编译
$ source oaienv  

$ ./cmake_targets/build_oai -I       # install SW packages from internet

# ./cmake_targets/build_oai  -w USRP --eNB # compile eNB
# 注意如果后续重新编译过limesdr的驱动,这部分也需要重新编译

$ ./cmake_targets/build_oai -c -w LMSSDR --eNB

下载并编译EPC(核心网)

$ git clone https://gitlab.eurecom.fr/oai/openair-cn.git

$ cd openair-cn

$ git checkout develop

$ git checkout 724542d0b59797b010af8c5df15af7f669c1e838 -b ubuntu16

#应用补丁 
$ git apply ../opencells-mods/EPC.patch

#对于国内的用户来说,国外的几个代码地址需要修改一下,否则会出现无法下载或者下载非常慢的情况
$ sed -i "s/git clone https:\/\/gitlab.eurecom.fr\/oai\/freediameter.git -b eurecom-1.2.0/wget https:\/\/www.mobibrw.com\/wp-content\/uploads\/2018\/03\/freediameter.tar.gz \&\& tar -zxvf freediameter.tar.gz \&\& cd freediameter \&\& git checkout eurecom-1.2.0 \&\& cd ../g" build/tools/build_helper

$ source oaienv; cd scripts

#安装依赖的软件,库
$ ./build_hss -i
# Do you want to install freeDiameter 1.2.0 ?<y/N>: yes
# 其他具体情况自行处理


#对于国内的用户来说,国外的几个代码地址需要修改一下,否则会出现无法下载或者下载非常慢的情况
$ sed -i "s/git clone git:\/\/git.osmocom.org\/libgtpnl/wget https:\/\/www.mobibrw.com\/wp-content\/uploads\/2018\/03\/libgtpnl.tar.gz \&\& tar -zxvf libgtpnl.tar.gz/g" ../build/tools/build_helper



#Install 3PP SW for mme and spgw
$ ./build_mme -i
# Do you want to install freeDiameter 1.2.0 ?<y/N>: no
# Do you want to install asn1c rev 1516 patched? <y/N>: no
# Do you want to install libgtpnl ? <y/N>: yes
# 其他具体情况自行处理



$ ./build_spgw -i
# Do you want to install libgtpnl ? <y/N>: no

#调整mme的编译模板,默认情况下mme编译出来的是Debug版本,
#但是这会触发"src/gtpv2-c/nwgtpv2c-0.11/src/NwGtpv2c.c"的断言异常
#”mme: ~/openair-cn/src/gtpv2-c/nwgtpv2c-0.11/src/NwGtpv2c.c:487: nwGtpv2cCreateLocalTunnel: Assertion `0' failed.“
#这个断言异常并不是大问题,直接无视即可
#因此我们把此处的编译调整为RelWithDebInfo
$ sed -i "s/\"Debug\"/\"RelWithDebInfo\"/g" ../build/mme/CMakeLists.template

#修正代码里面的几处问题
$ sed -i "s/while 0/while (0)/g" ../src/utils/log.h

$ sed -i 's/char[ \t]*pid_dec\[32]/char pid_dec\[128]/g' ../src/utils/pid_file.c

#正式进行编译操作
$ ./build_hss -c -v

$ ./build_mme -v

$ ./build_spgw -v

配置EPC

# 拷贝配置文件
$ cd ~

$ sudo mkdir -p /usr/local/etc/oai

$ sudo cp -rp opencells-mods/config_epc/* /usr/local/etc/oai


# 生成证书文件
$ cd openair-cn; source oaienv; cd scripts

$ ./check_hss_s6a_certificate /usr/local/etc/oai/freeDiameter hss.OpenAir5G.Alliance

$ ./check_mme_s6a_certificate /usr/local/etc/oai/freeDiameter mme.OpenAir5G.Alliance

# 配置出口网卡的名字,这个网卡用于访问互联网的时候使用
# 如果只有一块有线网卡,并且用这块有线网卡上网,则使用如下命令即可拿到网卡名
# `ifconfig | grep "Link" | awk '{print $1}' | grep "en"` 
# 其他情况请根据实际情况配置网卡
$ sudo sed -i "s/PGW_INTERFACE_NAME_FOR_SGI.*/PGW_INTERFACE_NAME_FOR_SGI = \"`ifconfig | grep "Link" | awk '{print $1}' | grep "en"`\";/g" /usr/local/etc/oai/spgw.conf

# 配置访问MySQL时候的密码,"/usr/local/etc/oai/hss.conf",此处假定MySQL的密码为"123"
$ sudo sed -i "s/^MYSQL_pass.*/MYSQL_pass = \"123\"/g" /usr/local/etc/oai/hss.conf


#导入数据库,建立表结构
$ ./hss_db_import 127.0.0.1 root 123 oai_db ~/opencells-mods/opencells_db.sql

修改我们UE需要使用的配置文件

$ cd ~

$ cd openairinterface5g; source oaienv

#配置文件为"targets/PROJECTS/GENERIC-LTE-EPC/CONF/"目录下的包含lmssdr的配置文件
$ sed -i "s/mobile_network_code.*/mobile_network_code = \"92\";/g" ./targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.lmssdr.conf

$ vim ./targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.lmssdr.conf

找到:

////////// MME parameters:
mme_ip_address      = ( { ipv4       = "192.168.12.148";
                          ipv6       = "192:168:30::17";
                          active     = "yes";
                          preference = "ipv4";
                        }
                      );

NETWORK_INTERFACES :
{
    ENB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
    ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.150/24";

    ENB_INTERFACE_NAME_FOR_S1U               = "eth0";
    ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.150/24";
    ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
};

替换为:

////////// MME parameters:
mme_ip_address      = ( { ipv4       = "127.0.0.20";
                          ipv6       = "192:168:30::17";
                          active     = "yes";
                          preference = "ipv4";
                        }
                      );

NETWORK_INTERFACES :
{
    ENB_INTERFACE_NAME_FOR_S1_MME            = "lo";
    ENB_IPV4_ADDRESS_FOR_S1_MME              = "127.0.0.10/8";

    ENB_INTERFACE_NAME_FOR_S1U               = "lo";
    ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.0.10/8";
    ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
};

测试功能,按照顺序打开四个独立Shell

$ echo -ne "\033]0;HSS\007" 

$ cd ~

$ cd openair-cn; source oaienv; cd scripts; 

#貌似需要运行之前先清理一下数据库才行,否则可能导致设备无法入网,应该是个BUG
$ ./hss_db_import 127.0.0.1 root 123 oai_db ~/opencells-mods/opencells_db.sql

$ ./run_hss

 

$ echo -ne "\033]0;MME\007" 

$ cd ~

$ cd openair-cn; source oaienv; cd scripts; 

$ ./run_mme

 

$ echo -ne "\033]0;SPGW\007" 

$ cd ~

$ cd openair-cn; source oaienv; cd scripts; 

$ sudo -E ./run_spgw

 

$ echo -ne "\033]0;EUE\007" 

$ cd ~

$ cd openairinterface5g; source oaienv

#配置文件为"targets/PROJECTS/GENERIC-LTE-EPC/CONF/"目录下的包含lmssdr的配置文件
#这个配置文件跟天线的接入方式直接相关,天线接入的是主板上的RX1_H,TX1_2这两个天线接口
#最后的-d 参数是启动图形界面分析流量

$ sudo -E ./cmake_targets/lte_build_oai/build/lte-softmodem -O ./targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.lmssdr.conf --rf-config-file ./targets/ARCH/LMSSDR/LimeSDR_above_1p8GHz_1v4.ini -d

#如果启动之后,出现 “[PHY][E]TX : Timeout (sent 6800/7680)” 这样的红色内容,然后退出,可以多尝试几次,一般就可以恢复正常了

正常启动之后,用手机(比如华为荣耀7)搜索运营型,可以找到一个名为20892的运营商,或者有些欧洲制式的手机可以正确的显示Eurecom这个法国电信运营商的名字。

继续阅读ubuntu 16.04系统LimeSDR V1.4使用OpenAirInterface搭建LTE实验环境