daemon.json配置docker容器日志大小及错误排查

docker日志目录:/var/lib/docker/containers/<容器id>/

docker容器的运行日志,如果不加以限制,会越来越大,占用非常大的磁盘空间。可以通过daemon.json配置docker日志文件大小,全局有效。

    docker安装后默认没有daemon.json这个配置文件,需要进行手动创建,docker不管是在哪个平台以何种方式启动, 默认都会来这里读取配置,使用户可以统一管理不同系统下的 docker daemon 配置。

    如果在daemon.json文件中进行配置,需要docker版本高于1.12,配置文件的默认径为:/etc/docker/daemon.json      

    该文件作为 Docker Engine 的配置管理文件, 里面几乎涵盖了所有 docker 命令行启动可以配置的参数。

如果没有daemon.json,新建一个,添加以下内容:

{
"exec-opts": [""],
"log-driver":"json-file",
 "log-opts": {
   "max-size": "300m",
   "max-file": "1"
 }
}

然后重启docker守护进程:

systemctl daemon-reload
systemctl restart docker

如果docker无法启动报错,使用dockerd查看输出错误信息:

dockerd

在网上看到docker无法启动后,systemctl status docker.service、cat /lib/systemd/system/docker.service等等,各种排查,其实都不能有效的找出错误原因,只有dockerd才是输出有效的错误信息。

另外需要注意,改动了daemon.json后,都一定是要运行systemctl daemon-reload和systemctl restart docker来重启docker。

使用cloudflare CDN的网站获取访客真实IP

之前有一篇文章是介绍宝塔获取cloudflare CDN访客真实IP的文章,但是那篇文章比较粗糙。下面结合cloudflare官方的说明文档,做一些补充说明。

一、CF-Connecting-IP 和 X-Forwarded-For

cloudflare将原始访问者 IP 地址显示在名为 CF-Connecting-IP 和 X-Forwarded-For 的附加 HTTP 标头中。所以你可以选择用:

real_ip_header CF-Connecting-IP; 

或者:

real_ip_header X-Forwarded-For;
real_ip_recursive on;

来获取访客真实IP。

二、ngx_http_realip_module模块

nginx服务器获取realip是依赖ngx_http_realip_module模块的,所以如果你用的是nginx,必须要编译ngx_http_realip_module模块。使用nginx -V命令查看nginx是否已经编译该模块,没有的话需要自己编译。

其它服务器参考cloudflare官方说明文档

三、set_real_ip_from的使用

如果是 set_real_ip_from 0.0.0.0/0; 则表示允许所有IP回源,会有安全隐患,我们可以设置为只允许cloudflare的IP回源:

server
{
listen 443 ssl http2;
listen [::]:80;
server_name 168itw.com;

set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2c0f:f248::/32;
set_real_ip_from 2a06:98c0::/29;

#X-Forwarded-For和CF-Connecting-IP二选一
real_ip_header    X-Forwarded-For;
real_ip_recursive on;
#real_ip_header CF-Connecting-IP; 

cloudflare IP段:https://www.cloudflare.com/ips/

注意:添加在nginx的http{}中,则全局应用在下面的所有server中,即所有网站生效;添加在网站对应的server{}中,则只有该网站中生效。

特别注意:如果同时运行了docker,且有反代docker服务,则需要将docker内网IP段也要加到set_real_ip_from中。

查看docker容器IP:

docker inspect 容器id

添加docker内网IP段:

set_real_ip_from 172.18.0.0/24

四、多级反向代理

如果cloudflare之后还有多级反向代理,可以在cloudflare后的第一级反代只允许cf IP回源,后面的允许上一级反代IP回源。

五、开启CLOUDFLARE的回源认证

cloudflare后台 SSL/TLS – Overview:SSL/TLS encryption mode设置为Full或者Full (strict)

SSL/TLS – Origin Server 开启:Authenticated Origin Pulls

在对应主机的配置文件的server块内加入下列代码:

ssl_client_certificate /etc/nginx/certs/cloudflare.pem;
ssl_verify_client on;

cloudflare.pem文件下载地址:https://developers.cloudflare.com/ssl/origin-configuration/authenticated-origin-pull/set-up/zone-level/

继续阅读

nginx禁止IP访问目录或文件及location匹配规则

一、关于deny和allow的使用

nginx通过ngx_http_access_module模块来控制IP访问特定路径,可以放在httpserverlocation中。比如:

location / {
    deny  192.168.1.1;
    allow 192.168.1.0/24;
    allow 10.1.1.0/16;
    allow 2001:0db8::/32;
    deny  all;
}

nginx按顺序检查规则,直到找到第一个匹配项。注意在使用指令时,如果最后不添加deny all,则可能会允许上面列出ip之外的其他ip均可访问,因为默认是allow all的。

   deny 43.243.12.116;
   deny 43.241.242.243;
   allow all;

所以,上面例子中最后的allow all可以不用添加,因为默认是allow all的。

二、nginx location 配置

  1. 禁止访问某些后缀文件
location ~ \.(ini|conf|txt)$ {
    deny all;
}

2. 禁止访问目录或目录下文件

#禁止访问目录
location ^~ /test/ {
    deny all;
}
#禁止访问目录下文件
location ^~ /test {
    deny all;
}

3. 禁止访问某个目录下的指定文件后缀文件

# 禁止访问某个目录下的 php 后缀文件
location /directory {
    location ~ .*\.(php)?$ {
    deny all;
    }
}
# 禁止访问多个目录下的 php 后缀文件
location ~* ^/(directory1|directory2)/.*\.(php)${
    deny all;
}

location可以嵌套使用,也就是说一个location中可以继续嵌套location。

三、location匹配规则详解

= 表示精确匹配

^~ 表示uri以某个字符串开头

~ 正则匹配(区分大小写)

~* 正则匹配(不区分大小写) !~和!~*分别为区分大小写不匹配及不区分大小写不匹配的正则

/ 任何请求都会匹配

匹配优先级: ​​= > ^~ > /​​

举例:

    location ~ .*\.(json)?$ {
    allow 127.0.0.1/16;
    deny all;
    expires      -1;
    }
  1. location: 表示定义一个匹配规则的位置块。
  2. ~: 表示后面跟着的是一个正则表达式,而不是普通的字符串匹配。
  3. .*: 表示匹配任意字符(除了换行符)零次或多次。这里是匹配任意字符零次或多次,即允许路径中包含任意字符。
  4. \.: 表示匹配点(.)字符。在正则表达式中,点(.)通常表示任意字符,但在这里通过反斜杠进行转义,表示匹配实际的点字符。
  5. (json)?: 表示匹配括号内的内容零次或一次,即json可选。这里的括号用于创建一个捕获组,表示括号内的内容是一个整体,而问号表示前面的字符(这里是 (json))可选。
  6. $: 表示匹配字符串的结尾。

参考文档:

继续阅读

清理docker占用的硬盘空间

docker system 命令

docker system df命令,类似于 Linux 上的df命令,用于查看 Docker 的磁盘使用情况:

docker system df
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              147                 36                  7.204GB             3.887GB (53%)
Containers          37                  10                  104.8MB             102.6MB (97%)
Local Volumes       3                   3                   1.421GB             0B (0%)
Build Cache                                                 0B                  0B

docker system prune命令可以用于清理磁盘,删除关闭的容器、无用的数据卷和网络,以及 dangling 镜像(即无 tag 的镜像)。

docker system prune -a命令清理得更加彻底,可以将没有容器使用 Docker 镜像都删掉。

注意,这两个命令会把你暂时关闭的容器,以及暂时没有用到的 Docker 镜像都删掉了…所以使用之前一定要想清楚吶。

手动清理

  1. 清理无用的容器

使用命令docker ps -a列出所有容器,找出不再需要的容器,使用命令docker rm <container_id>删除它们。在删除容器之前,可以使用命令docker stop <container_id>先停止容器。

  1. 清理无用的镜像

使用命令docker images列出所有镜像,找出不再需要的镜像,使用命令docker image rm <image_id>删除它们。在删除镜像之前,可以使用命令docker stop <container_id>先停止容器。

  1. 清理无用的数据卷

使用命令docker volume ls列出所有数据卷,找出不再需要的数据卷,使用命令docker volume rm <volume_name>删除它们。在删除数据卷之前,需要先删除使用该数据卷的容器。

  1. 清理无用的网络

使用命令docker network ls列出所有网络,找出不再需要的网络,使用命令docker network rm <network_name>删除它们。在删除网络之前,需要先删除使用该网络的容器。

5. 清理Docker日志

Docker日志会占用大量空间,可以使用命令docker logs --tail 50 <container_id>来查看最近50行的日志。如果需要清理全部日志,可以使用命令truncate -s 0 /var/lib/docker/containers/*/*/*.log来清空所有日志文件。

Nginx secure_link模块给网站添加防盗链

网站上的一些静态资源文件,比如图片、pdf、压缩文件、m3u8等视频文件,经常会被盗链,之前我都是用referrer来防盗链,但是referrer太容易伪造了。后来nginx的secure_link可以很好的解决这个问题。

该模块有三个指令,分别为:secure_link、secure_link_md5、secure_link_secret,使用方法有两种:

  1. secure_link + secure_link_secret(v0.7.18以后);
  2. secure_link + secure_link_md5(v0.8.5以后,其实就是用来替代第一种的)。

后面的部署过程我们都是采用方法2。

secure_link + secure_link_md5基本原理

  1. 把一些参数以及过期时间按你想要的顺序拼成一个字符串,然后对它做md5计算,然后把这个md5和过期时间以参数的方式附加到链接后面。
  2. 在nginx中我们配置同样的参数串顺序,nginx会按我们给出的参数串计算出它的md5值,然后把它计算得到的md5值与链接中传过来的md5值作对比,如果两个值不相同,则会把变量$secure_link设置为空字符串。
  3. 如果md5值相同,nginx还会继续对比过期时间,如果链接已经过期(其实就是当前时间戳大于链接中传过来的时间戳),那么它会把$secure_link的值置为”0″,否则为”1″。
  4. 综上,我们只需要用if检测$secure_link的值,如果为空,则说明这个链接不是合法链接,如果不为空,则继续用if检测它的值是否为”0″,,只要为空或为0,那么我们就可以判断它不是合法请求,就可以用return 403或者rewrite的方式去处理这种不合法请求;

以下记录整个过程。

1、编译secure_link模块

我用的是宝塔,默认是没有编译secure_link,通过查看nginx -V确认下:

/www/server/nginx/sbin/nginx -V
cd /www/server/nginx/src/

在最后面添加–with-http_secure_link_module,编译:

./configure  --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-module --with-http_secure_link_module
make

备份nginx:

cp /www/server/nginx/sbin/nginx /www/server/nginx/sbin/nginx.bak

停止nginx:

nginx -s stop

继续:

cp /www/server/nginx/src/objs/nginx /www/server/nginx/sbin/nginx

然后启动nginx

systemctl restart nginx

查看nginx -V是否成功编译secure_link模块:

/www/server/nginx/sbin/nginx -V

2、Nginx配置

location /yourpath/ {
    secure_link $arg_md5,$arg_expires; #这里配置了2个参数一个是arg_md5,一个是arg_expires
    secure_link_md5 "123456$uri$arg_expires"; #123456为自定义的加密串(这里的md5加密顺序要和程序生成的加密顺序保持一致)   

    if ($secure_link = "") {
        return 403; #资源不存在或哈希比对失败
    }

    if ($secure_link = "0") {
        return 410; #时间戳过期 
    }
}

3、配置网站PHP

<?php
$secret = '123456';

####下载文件,切记路径带上/
$path = "/file/168itw.zip";

####下载到期时间,time是当前时间,$validtime表示有效期,也就是说从现在到300秒之内文件不过期
$validtime = 300;
$expire = time() + $validtime;

####用文件路径、密钥、过期时间生成加密串(注意这里的md5加密顺序要和nginx配置文件中的顺序保持一致)
$md5 = base64_encode(md5($secret . $path . $expire, true));
$md5 = strtr($md5, '+/', '-_');
$md5 = str_replace('=', '', $md5);

####加密后的下载地址
$uri = $path . '?md5=' . $md5 . '&expires=' . $expire;

####安全下载链接可以直接echo输出
$uri = "https://www.168itw.com" . $uri;
?>

输出上述文件链接:

<?php echo $uri; ?>

如果使用的是wordpress,需要在文章post中添加防盗链文件,可以安装Insert PHP Code Snippet插件,这样就可以在任意文章中任何位置插入PHP代码。

参考文章:https://www.xiebruce.top/1799.html

RealVNC: VNC Server has no authentication schemes configured错误

RealVNC连接远程server端的时候,提示:VNC Server has no authentication schemes configured. 错误。

解决方法:

  1. 在server端打开Powershell
  2. 输入以下命令:
New-ItemProperty -Path "HKLM:\Software\RealVNC\vncserver" -Name "Authentication" -Value "VncAuth"
& "C:\Program Files\RealVNC\VNC Server\vncpasswd.exe" -service

按提示输入密码。

重新连接realvnc,输入刚才的密码即可成功连接。

Linux设置IPv4优先

IPv6 VPS套了warp后变成了IPv4和IPv6双栈,如何设置IPv4优先呢?

以debain为例,直接修改 /etc/gai.conf 文件:

vi /etc/gai.conf

#precedence ::ffff:0:0/96 100
把前面的”#”去掉即可。

或者:

echo "precedence ::ffff:0:0/96 100" >>/etc/gai.conf

Debian部署go项目

第一次部署go项目,记录一下过程。

首先update一下:

apt update
apt upgrade

安装nodejs:

apt install nodejs

安装npm:

apt install npm

安装pm2:

npm install pm2 -g

将编译好的go项目文件上传到对应目录之后:

chmod +x golang

运行go项目:

pm2 start golang

查看:

pm2 ls

Linux设置swap交换分区

以debian为例。

创建交换空间文件/swapfile,大小是1G:

fallocate -l 1G /swapfile

默认交换空间文件的权限只有root用户才能写入和读取交换文件的数据。因此我们需要修改交换空间文件的权限为600,并使用mkswap格式化文件。

chmod 600 /swapfile
mkswap /swapfile

启用交换空间:

swapon /swapfile

要在Linux系统启动时自动挂载分区,需要在/etc/fstab文件中定义挂载配置选项:

echo "/swapfile swap swap defaults 0 0" | sudo tee -a /etc/fstab

运行命令swapon或free命令验证交换空间是否处于活动状态:

swapon --show
free -h

Swappiness

Swappiness是一个Linux内核属性,用于定义系统使用交换空间的频率。Swappiness可以是0到100之间的值。

swappiness=0的时候表示最大限度使用物理内存,然后才是交换空间,swappiness=100的时候表示积极的使用交换空间。

Linux的初始默认设置为60,你可以运行命令cat /proc/sys/vm/swappiness命令查看当前swappiness值的大小。

如果你需要对swappiness的值作出更改,请运行sudo sysctl -w vm.swappiness=10命令。

sysctl命令用于在运行时配置Linux内核的参数,更改仅在当前会话中可用,即重启会恢复为默认值。

为让swappiness的值持久化,则需要将值写入到/etc/sysctl.conf文件中。sysctl.conf是Linux内核的配置文件。在Linux内核启动是将会次配置文件的参数。

运行以下命令持久化Linux内核参数swappiness的值:

echo "/swapfile swap swap defaults 0 0" | sudo tee -a /etc/sysctl.conf

debian设置ssh密钥登录

1、生成密钥

ssh-keygen

或者:

ssh-keygen -t rsa

一路回车即可。在 root 用户目录中生成了一个 .ssh 目录,内含两个密钥文件。id_rsa 为私钥,id_rsa.pub 为公钥。

2、在服务器上安装公钥

[root@host ~]$ cd .ssh
[root@host .ssh]$ cat id_rsa.pub >> authorized_keys

如此便完成了公钥的安装。为了确保连接成功,请保证以下文件权限正确:

[root@host .ssh]$ chmod 600 authorized_keys
[root@host .ssh]$ chmod 700 ~/.ssh

3、设置 SSH,打开密钥登录功能

编辑 /etc/ssh/sshd_config 文件,进行如下设置(删除这两行前面的注释#):

AuthorizedKeysFile      .ssh/authorized_keys .ssh/authorized_keys2
PubkeyAuthentication yes

168itw注:AuthorizedKeysFile不启用,貌似也不影响,没明白这里的作用!

确保允许root 用户通过 SSH 登录:

PermitRootLogin yes

重启ssh服务:

service sshd restart

切换为root用户和密码登录后,下载 .ssh 目录下的私钥文件id_rsa,导入ssh客户端。

确保root用户能够通过密钥登录。

当你完成全部设置,并以密钥方式登录成功后,再禁用密码登录:

PasswordAuthentication no

最后,重启 SSH 服务:

[root@host .ssh]$ service sshd restart
继续阅读