Debian安装各种软件

filebrowser

ilebrowser 是一个使用 go 语言编写的软件,功能是可以通过浏览器对服务器上的文件进行管理。可以是修改文件,或者是添加删除文件,甚至可以分享文件,是一个很棒的文件管理器,你甚至可以当成一个网盘来使用。

仓库地址: https://github.com/filebrowser/filebrowser

下载压缩包,解压后,赋予执行权限,直接运行二进制文件即可。首次运行会在当前目录下生成 filebrowser.db 的数据库文件,里面包含各种配置信息。

常用命令

./filebrowser help  # 查看帮助信息

# 配置相关命令
./filebrowser config cat  # 查看配置信息(数据库文件里的)
./filebrowser config set -p 18848  # 设置端口号
./filebrowser config set -a 192.168.0.211  # 设置监听的IP地址(0.0.0.0:监听所有网卡地址)
./filebrowser config set -r /  # 设置根目录

# 运行
/opt/filebrowser/filebrowser -d /opt/filebrowser/filebrowser.db # -d:指定数据库文件路径,默认是在你所在的当前目录下

关于根目录:默认是显示 filebrowser 的程序所在目录,可以通过网页的设置-用户设置-编辑用户-根目录进行设置。注意一点,网页上修改的地址,是基于当前根目录下进行拼接的,例如,我这里是 /srv 目录,在用户页面设置修改根目录为 /root,结果报错,lstat /srv/root: no such file or directory,他将 /root 拼接在了/srv 下面,这并不是我想要的,所有通过命令将根目录设置为 /,这样就行了。

MariaDB

安装:apt install mariadb-server

运行安全检查脚本:sudo mysql_secure_installation

在默认情况下,MariaDB 的 root 用户是使用 unix_socket 插件进行身份验证的。这意味着只有在操作系统上有 root 权限的用户才能登录为 root 用户。但是,有些情况下我们可能希望使用密码进行身份验证,而不是依赖操作系统的权限。

将 root 用户的身份验证方式修改为 mysql_native_password 插件。使用 root 用户登录数据库

-- 进入 mysql 这个数据库
USE mysql;
-- root只能服务器本地登录
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
-- root可以远程登录
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'ALY#root123';
-- 刷新权限
FLUSH PRIVILEGES;

创建一个用户,具备管理员权限

-- 创建一个用户
CREATE USER 'myadmin'@'%' IDENTIFIED BY 'admin123';
-- 赋予所有权限
GRANT ALL PRIVILEGES ON *.* TO 'myadmin'@'%' WITH GRANT OPTION;
-- 刷新权限
FLUSH PRIVILEGES;

卸载 mariadb

# 删除配置文件、数据文件mariadb-server的依赖包和mariadb-server本身
apt-get purge --auto-remove mariadb-server

Nginx

安装:apt install nginx

nginx 配置文件


root、alias 配置区分: https://zhuanlan.zhihu.com/p/131009164

php 相关配置

server {
		.....
        # pass PHP scripts to FastCGI server
        #location ~ \.php$ {
        #       include snippets/fastcgi-php.conf;
        #
        #       # With php-fpm (or other unix sockets):
        #       fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass 127.0.0.1:9000;
        #}

        location ~ \.php$ {
		        fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
                fastcgi_pass unix:/run/php/php5.6-fpm.sock; # 使用unix sockets
                # fastcgi_pass 127.0.0.1:9000; # tcp sockets
        }
}

反向代理配置

server {
    listen       80; # 代理服务器监听的端口
    server_name  192.168.10.1;# 代理服务器地址或绑定域名

	# 访问 http://192.168.10.1/ ,到 http://192.168.10.2上
    location / { # 访问 80 端口后的所有路径都转发到 proxy_pass 配置的 ip 中
   		proxy_pass http://192.168.10.2 ; # 配置真实网站的 ip 地址和端口号 【注:url 地址需加上 http:// 或 https://】   		
    }

	# 访问 http://192.168.10.1/dvwa/这个路径 ,实际代理到 http://127.0.0.1:49154/
    location /dvwa/ {
        proxy_pass http://127.0.0.1:49154/ ; # 加不加 / 的区别。绝对路径和相对路径的区别
        # 加反斜杠:访问 http://192.168.10.1/dvwa/代理到http://127.0.0.1:49154/下
		# 不加反斜杠:访问 http://192.168.10.1/dvwa/代理到http://127.0.0.1:49154/dvwa/下
        proxy_redirect  / /dvwa/; # 处理 302 跳转事件,将 location 的 / 路径,替换为/dvwa/,保证路径的正确。
    }

	# 访问 http://192.168.10.1/pikachu/这个路径 ,实际代理到 http://127.0.0.1:49156/
    location /pikachu/ {
        proxy_pass http://127.0.0.1:49156/ ;
    }

	# 访问 http://192.168.10.1/sqli-lab/这个路径 ,实际代理到 http://127.0.0.1:49158/
    location /sqli-lab/ {
        proxy_pass http://127.0.0.1:49158/ ;
    }

}

ssl 配置

server {
	#监听443端口
    listen 443 ssl; # 推荐使用这种方式
    #你的域名
    server_name lanhuli.top;
    
    # ssl on;  # 不建议使用 ssl 方式
    #ssl证书的pem文件路径
    ssl_certificate  /root/cert/ www.lanhuli.top.pem ;
    #ssl证书的key文件路径
    ssl_certificate_key /root/cert/ www.lanhuli.top.key ;

    location / {
	     root /var/ www/html ;
	     index index.php index.html;
    }

	location ~ \.php$ {
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME /var/ www/html$fastcgi_script_name ;
		fastcgi_pass unix:/run/php/php8.0-fpm.sock;
	}

}

server {
    listen 80;
    server_name lanhuli.top;
    #将请求转成https
    rewrite ^(.*)$ [https://$host$1](https://$host$1) permanent;
}

basic 认证配置

1)使用本机认证:auth_basic。还有另一种方式,这个比较简单,就用这个就行。

需要先安装 htpasswd 工具:yum install httpd-tools 或者 apt install apache2-utils

生成密码文件:htpasswd -c ./mypasswd 用户名,然后输入密码。这个存放的文件路径可以随意指定(这个文件的存放路径必须要让 Nginx 有权限访问到。可以放到 /usr/local/share/mypasswd)。

2)修改 Nginx 的配置文件

注意:不要修改 Nginx 自带的默认配置文件,一定要新建一个配置文件。

新建配置文件:touch /etc/nginx/conf.d/my-nginx.conf

写入内容

server {
    listen 26660; # 监听端口
    server_name 127.0.0.1;
    index index.html;
    
    # auth_basic 认证配置,就这两行
    auth_basic "请输入账号密码";  # 这里是验证时的提示信息
    auth_basic_user_file /usr/local/share/mypasswd; # 注意,这个文件的存放路径必须要让 Nginx 有权限访问到,不然报错

    # Nginx 代理转发
    location /  {
        proxy_pass http://127.0.0.1:80 ;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

如果使用 curl 和 wget 命令进行下载:

curl -u username:password URL
wget --http-user=username --http-passwd=passwd URL

上传文件限制大小问题

1)nginx 配置问题

nginx 服务器报错:413 Request Entity Too Large

打开配置文件 /etc/nginx/nginx.conf。在 http{}段中加入 client_max_body_size 100m; 100 m 为允许最大上传的大小。然后重启 nginx

2)php 配置问题

上传的文件大小超过 php.ini 文件中定义的 upload_max_filesize 值

打开 php.ini,把 upload_max_filesize 和 post_max_size 修改为 100 M,然后重启。

注意:

通过 find 命令查找发现有两个 php.ini 文件

查看 phpinfo,发现使用的是 fpm 下的文件

webdav 服务

server {
    listen 80;
    server_name localhost;
    
	# 设置使用utf-8编码,防止中文文件名乱码
    charset utf-8;

	# 默认存放文件的路径
	root /home/dav;

    auth_basic              realm_name;
    # 用户密码文件存放位置
    auth_basic_user_file    /etc/nginx/.passwords.list;

    # dav 允许的操作
    dav_methods     PUT DELETE MKCOL COPY MOVE;
    dav_ext_methods PROPFIND OPTIONS;
    
    # 创建文件的默认权限
    dav_access      user:rw group:rw all:r;

    # 临时文件位置
    client_body_temp_path   /tmp;
    
    # 最大上传文件限制, 0表示无限制
    client_max_body_size    0;
    
    # 允许自动创建文件夹(如果有需要的话)
    create_full_put_path    on;
    
    # 自动生成索引(没有显示403,但是可以下载文件)
    autoindex on;
}

问题

实现 http 和 https 复用 1 个端口的 2 种解决方式

server {
	# 只用一个非标准端口实现 http://example.com:3333 -> https://example.com:3333
	error_page 497 https://$host:3333$request_uri;
	# https://$host:$server_port$request_uri;  # 这样也可以
	# error_page 502 503 /50x.html;
}

参考:

Nginx 报错:nginx: [emerg] unknown directive “ “ in /etc/nginx/conf.d/XXX.conf:122

该问题为文本从 Windows 中拷入 Linux,空格编码不统一。使用命令查看 cat -A /etc/nginx/conf.d/XXX.conf

删除这些空格,重新替换为普通空格即可

nextcloud

用 docker 安装

# 创建一个自定义网络,并指定网段
docker network create --subnet 172.16.7.0/24 my_network 
# 创建nextcloud容器,并分配一个固定IP地址
docker run -d --restart=always\
  --name=nextcloud\
  -p 18849:80\
  -v /opt/nextcloud/nextcloud-data:/var/www/html\
  --network my_network\
  --network-alias nextcloud\
  --ip 172.16.7.2
  registry.cn-hangzhou.aliyuncs.com/lanhuli/nextcloud:30.0

说明:

  • 关于 /var/ www/html 目录:在个目录下,有个 data 目录存放这我们的云盘数据,config 目录有相关配置文件等。所以直接映射了整个 /var/ www/html 目录,方便后续操作。
  • 这里我并没有开放云服务器 18849 端口,因为后续打算使用服务器自带的 Nginx 进行反向代理,并配置 https 访问,所以不映射容器端口也行。
  • 创建一个自定义网络是为了固定容器的 IP 地址,docker 默认是按容器的启动顺序来分配随机 IP 地址的,为了保证反向代理成功,必须固定 IP,不然每次重启系统,容器的 IP 都会变化,很麻烦。
  • 查看 nextcloud 容器的内网 IP 地址:docker inspect nextcloud | grep Address

目录结构

/var/ www/html/ :nextcloud 的网站根目录,这下面有很多文件和文件夹,例如

  • data:用户的数据目录,上传的文件,SQLite 的数据库文件等在这里。
  • data/owncloud.db:默认 SQLite 的数据库文件
  • data/appdata_:程序运行所产生的文件。例如:预览,存放预览图
  • data/updater_:更新前系统的备份,自动清除
  • data/nextcloud.log:日志,可清空
  • data/your-username:上传的文件,文件历史版本,回收站等
  • config:php 的配置文件和其他配置文件的存放目录。
  • apps:应用商店插件安装目录,可以手动下载插件,解压到此目录下。

配置 https 访问

使用 Nginx 反向代理,并配置 https。创建一个配置文件:vim /etc/nginx/conf.d/nextcloud.conf

准备证书(pem 和 key 文件),放到服务器上,我这里放到了 /opt/nextcloud/ssl_zhengshu/ 目录下。在 Nginx 的配置目录下新建一个配置文件,写入一下内容。

server {
    listen       19001 ssl;  # 服务器监听的端口
	server_name  x.x.x.1;  # 服务器地址或绑定域名
	
	client_max_body_size 500M;  # 设置上传文件的大小限制
	error_page 497 https://$host:19001$request_uri;  # 强制浏览器使用https访问。详情见 问题4
    
	# 设置ssl
	# ssl证书的pem文件路径
	ssl_certificate /opt/nextcloud/ssl_zhengshu/cert.pem;
	# ssl证书的key文件路径
	ssl_certificate_key /opt/nextcloud/ssl_zhengshu/private.key;

    # 访问 http://x.x.x.1:19001,Nginx 转到 http://172.16.7.2 上
    location / {
    	# 访问 19001 端口后的所有路径都转发到 proxy_pass 配置的ip中
		proxy_pass http://172.16.7.2;  # 这是 nextcloud 容器的内网IP地址,和端口号 【注:url地址需加上http:// 或 https://】
		proxy_set_header HOST $host:$server_port;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
    }

}

注意:直接复制的话 nginx 报错 unknown directive " ",参考: https://blog.csdn.net/Min_Chander/article/details/100659958

出现的问题

1)通过不被信任的域名访问

找到 /var/ www/html/nextcloud/config/config.php 文件,修改 trusted_domains 配置代码。可以在数组后面追加,也可以直接一劳永逸。

'trusted_domains' => array(
//   0 => '127.0.0.1',
     0 => $_SERVER['HTTP_HOST'],  // 一劳永逸
),

参考: https://www.cnblogs.com/jsrd/p/17488223.html

2)使用自定义的 https 证书,客户端连接报错

在 config.php 内修改一行配置,没有就添加一行(注意位置)

'overwriteprotocol' => 'https',  # 改为 https

3)关闭 nextcloud 自带的暴力破解防护

暴力破解防护默认开启,可手动关闭,参考: https://rangotec.com/blog/50.html

在 config.php 内添加一行配置,注意添加位置

'auth.bruteforce.protection.enabled' => true,

4)nextcloud 检查报错

  • 服务器没有配置维护时段开始时间。这意味着资源密集型日常后台作业也将在您的主要使用时间执行。我们建议将其设置为低使用率的时间,这样用户就不会受到这些繁重任务造成的负载的影响。

解决方法:在 config/config.php 中,添加如下配置。值为 1 时将仅在 UTC 时间凌晨 1 点到 UTC 时间凌晨 5 点之间运行这些后台作业。

'maintenance_window_start' => 1,
  • 检测到一些缺失的可选索引。偶尔会添加新索引(由 Nextcloud 或已安装的应用程序添加)以提高数据库性能。

解决方法:运行命令

docker exec -u www-data -it nextcloud php occ db:add-missing-indices
# nextcloud 是容器的别名,也可以用容器id代替
  • 上次后台作业执行运行了 6 小时前。似乎有些不对劲(定时任务修改)

解决方法:docker 运行的定时任务需要使用宿主机的 crontab 命令执行,使用 cron 方式。

docker exec -u www-data -it nextcloud php cron.php

将上面这条命令加入宿主机的 crontab 里面,每隔 5 分钟执行一次。

  • 请确保将 config.php 文件中的 "overwrite.cli.url" 选项设置为用户主要用来访问此 Nextcloud 的 URL。

解决方法:修改配置文件 config.php ,按它建议的 URL 来。

'overwrite.cli.url' => 'https://x.x.x.x:8888'
  • 您的实例上的某些标头设置不正确 - 未设置 Strict-Transport-Security HTTP 标头(应至少为 15552000 秒)。为了增强安全性,建议启用 HSTS。

解决方法:我这里使用了 Nginx 反向代理,所以需要修改 Nginx 的反向代理配置文件

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

5)配置商店镜像源

修改 config.php 文件,添加配置

'appstoreenabled' => true, // appstorre
'appstoreurl' => 'https://www.orcy.net/ncapps/v2/',

备份

注意:我是 docker 版本安装的,直接用的 SQLite 数据库,所以不用去导出数据库备份。

只需要备份数据目录 date 文件夹,手动修改的配置文件,如 config.php 文件,宿主机的 Nginx 配置文件

data 文件夹:rsync 进行备份

config.php:目前配置文件所做的修改有 3 处

// 解决访问不被信任的问题
'trusted_domains' => array(
//   0 => '127.0.0.1',
     0 => $_SERVER['HTTP_HOST'],
),

// 客户端使用https登录报错问题
'overwriteprotocol' => 'https',  # 改为 https

// 关闭暴力破解防护
'auth.bruteforce.protection.enabled' => true,

Nginx 配置:复制并保存配置文件即可

迁移或恢复

注意:我是 docker 版本安装的,直接用的 SQLite 数据库,所以不用去导出数据库备份。

1)在新服务器上重新创建 nextcloud 容器,映射好目录后,启动。

2)打开 web 界面,然后创建一个和之前一样的用户名和密码的管理员账号。创建好后,登录成功,然后退出。

3)停止容器,删除 data 目录。然后用 rsync 命令将备份的 date 目录同步到容器映射的目录下。

4)重新启动容器,然后登录即可。

这样,就成功进行了服务器的迁移或恢复数据。文件的历史版本,回收站,网页的设置等都是和之前一样的,没有改变。

rsync 同步命令:rsync -Aax source/data/ destination/data

因为我还使用 Nginx 进行了反向代理和配置 https 访问等,所以还需要对 Nginx 进行配置的迁移,并修改部分参数值,这个就简单了。

出现的问题:

  • 用户名和密码都对,就是无法登录,一直跳转到登录页面:换个浏览器试试

rsync

参考: https://www.ruanyifeng.com/blog/2020/08/rsync.html

安装:apt install rsync

常用参数

  • -a:以递归方式传输文件,并保持所有文件的属性,等同于-rlptgoD
  • -r:递归复制整个目录
  • -l:保留软链接
  • -p:保留文件的权限标记
  • -t:保留文件的时间标记
  • -g:保留文件的属组标记
  • -o:保留文件的属主标记
  • -D:保留设备文件及其他特殊文件
  • -v:详细模式,输出详细的处理过程
  • - n:模拟命令执行的结果,并不真的执行命令
  • --exclude:同步时排除文件
  • --delete:删除那些目标目录中有而源目录中没有的多余文件

注意,-r 参数是必须的,否则 rsync 运行不会成功,-a 参数可以替代 -r

常用实例

1)本地同步

本地目录 source 同步到本地目录 destination

rsync -a source destination
rsync -a source1 source2 destination  # 同步两个文件夹

目标目录 destination 如果不存在,rsync 会自动创建。执行上面的命令后,源目录 source 被完整地复制到了目标目录 destination 下面,即形成了 destination/source 的目录结构。

如果只想同步源目录 source 里面的内容到目标目录 destination,则需要在源目录后面加上斜杠。

rsync -a source/ destination

上面命令执行后,source 目录里面的内容,就都被复制到了 destination 目录里面,并不会在 destination 下面创建一个 source 子目录。

2)远程同步

rsync 除了支持本地两个目录之间的同步,也支持远程同步。它可以将本地内容,同步到远程服务器。

rsync -av source/ username@remote_host:destination

也可以将远程内容同步到本地。

rsync -av username@remote_host:source/ destination
rsync -av root@192.168.1.2:/opt/mybooks/ /opt/mybook

rsync 默认使用 SSH 进行远程登录和数据传输。需要手动输入服务器用户密码

3)同步时排除某些文件

--exclude:不仅仅可以排除本地目录或文件,也可以忽略远程的文件

# 排除 src_directory 目录下的file.txt文件
rsync -a --exclude 'file.txt' src_directory/ dst_directory/
# 排除 dir1 目录
rsync -a --exclude 'dir1' src_directory/ dst_directory/
# 排除 dir1 目录下的所有文件,但是保留 dir1 目录
rsync -a --exclude 'dir1/*' src_directory/ dst_directory/
# 排除多个文件或目录
rsync -a --exclude 'file1.txt' --exclude 'dir1/*' --exclude 'dir2' src_directory/ dst_directory/
# 可以用大括号 {} 列出要排除的文件和目录并用逗号分隔
rsync -a --exclude={'file1.txt','dir1/*','dir2'} src_directory/ dst_directory/
# 从文件读取排除列表
rsync -a --exclude-from='exclude-file.txt' src_directory/ dst_directory/
# 排除所有 jpg 文件
rsync -a --exclude '*.jpg*' src_directory/ dst_directory/

# 忽略远程的文件夹
# remote_dir 文件夹本地没有,但是远程有。使用--delete参数会将其删除。如果想保留远程的remote_dir文件夹,可以使用--exclude参数
rsync -a --delete --exclude={'file1.txt','dir1/*','dir2','remote_dir'} src_directory/ dst_directory/

参考: https://www.myfreax.com/how-to-exclude-files-and-directories-with-rsync/

免密码进行同步

简单的 rsync 操作,往往需要和用户交互,需要用户输入密码,这个对于结合应用系统使用,比如 Java 调用 linux 指令实现同步的话,就不是很方便。

有两种方法:利用 ssh 的安全校验机制来传输文件,然后将 ssh 设置为免密码登录。或者将 rsync 以 daemon 的方式启动,通过配置文件设定账号密码。

1)ssh 免密登录

假设服务器 A 是客户端,在 A 上通过 ssh 连接服务器 B。

需要在服务器 A 上执行一下命令

ssh-keygen -t rsa  # 连续敲3次回车即可。默认在用户的根目录下生成一个 .ssh 的文件夹

每个文件的作用:

  • authorized_keys:存放远程免密登录的公钥,主要通过这个文件记录多台机器的公钥。
  • id_rsa:生成的私钥文件
  • id_rsa.pub:生成的公钥文件
  • known_hosts:已知的主机公钥清单

然后上传公钥到目标服务器 B(ip 地址:192.168.1.100)

ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.100 # 注意B的登录用户名

然后输入服务器 B 的 root 密码即可。

测试:在服务器 A 直接 ssh 连接服务器 B, ssh root@192.168.1.100

参考: https://www.cnblogs.com/hanwen1014/p/9048717.html

2)以 daemon 的方式启动

参考: https://www.cnblogs.com/shihuc/p/5628893.html

坚果云同步案例

# 笔记存放在目录 /opt/坚果云笔记
rsync -a --exclude={'.obsidian','.trash','.stignore','.stfolder'} /srv/share/坚果云笔记 root@8.140.21.107:/opt

# 同步小说
rsync -a /srv/share/komga/data/小说完 root@8.140.21.107:/opt/webdav/moon_reader
# 同步小说,同时删除本地目录里面没有,但是远程目录里有的文件。就是远程目录多的文件要删除掉
rsync -a --delete /srv/share/komga/data/小说完 root@8.140.21.107:/opt/webdav/moon_reader

ufw

安装:sudo apt install ufw

安装好后,默认未启用。可以用 sudo ufw status 查看状态(不要用 systemctl 命令操作,没有效果)

sudo ufw status   # 查看状态
sudo ufw enable   # 启用防火墙
sudo ufw disable  # 禁用防火墙
sudo ufw reset    # 重置配置,恢复到初始状态
sudo ufw status verbose  # 查看配置的规则

配置

sudo ufw allow ssh  # 允许 SSH 连接
sudo ufw allow ssh comment "ssh服务使用"  # comment 参数可以添加备注 
sudo ufw allow 22   # 通过指定端口号来允许 SSH 连接(默认端口为22)
sudo ufw deny ssh   # 拒绝 SSH 连接
sudo ufw deny 22    # 通过端口号拒绝

删除配置

# 按规则号删除
sudo ufw status numbered  # 查看规则编号
sudo ufw delete 4  # 删除规则编号为4的规则

# 按规则来删除
sudo ufw delete allow 8080  # 删除打开8080端口的规则

参考:

rsyslog 日志服务器搭建

安装:apt install rsyslog

查看版本:rsyslogd -v

编辑配置文件 /etc/rsyslog.conf

# 加载必要模块
module(load="imuxsock")   # 本地日志支持
module(load="imudp")      # UDP 接收
module(load="imtcp")      # TCP 接收

# 输入配置:允许接收远程日志
input(type="imudp" port="514" ruleset="remote")
input(type="imtcp" port="514" ruleset="remote")

# 定义日志存储规则集
ruleset(name="remote") {
    # 按来源 IP 分目录存储(模板定义)
    $template RemoteLogDir, "/var/log/remote/%fromhost-ip%/%$YEAR%-%$MONTH%-%$DAY%.log"
    
    # 过滤非本地日志并存储
    if ($fromhost-ip != '127.0.0.1') then {
        action(
            type="omfile"
            dynaFile="RemoteLogDir"
            dirCreateMode="0755"
            FileCreateMode="0644"
        )
        stop  # 停止后续处理
    }
}

# 本地日志单独存储(可选)
$template LocalLogDir, "/var/log/local/%programname%/%$YEAR%-%$MONTH%-%$DAY%.log"
if ($fromhost-ip == '127.0.0.1') then ?LocalLogDir

检查配置语法是否证券

sudo rsyslogd -N1 -f /etc/rsyslog.conf
# 无输出表示配置正确,否则显示错误信息

重启服务使配置生效: sudo systemctl restart rsyslog

测试配置

# 从另一台设备发送测试日志(替换 IP 为 Rsyslog 服务器地址)
logger -n 192.168.1.100 -P 514 -T "Test message from remote device"

# 查看存储的日志文件
ls /var/log/remote/192.168.1.50/  # 应看到按日期命名的日志文件
tail /var/log/remote/192.168.1.50/2024-07-15.log

目录结构

/var/log/remote/
├── 192.168.1.50/
│   ├── 2024-07-15.log
│   └── 2024-07-16.log
└── 192.168.1.60/
    ├── 2024-07-15.log
    └── 2024-07-16.log

阿里云 OSS 存储桶访问

Python 环境

apt install python3.9  # 安装Python环境
apt install python-dev  # 安装python-devel包
pip install oss2  # 安装SDK
pip install flask  # 

参考: https://help.aliyun.com/zh/oss/developer-reference/installation-14

export OSS_ACCESS_KEY_ID=your_access_key_id
export OSS_ACCESS_KEY_SECRET=your_access_key_secret

export OSS_ACCESS_KEY_ID=Lxxxxxxxxxxx
export OSS_ACCESS_KEY_SECRET=4cxxxxxxxxxxxx
bucket_name = 'lanhuli-file'  # 替换为你的 Bucket 名称
region = 'oss-cn-hongkong.aliyuncs.com'        # 替换为你的 Region

alpine

# 先升级
/usr/local/bin/python -m pip install --upgrade pip
apk update && apk add python3-dev gcc libc-dev
apk add libffi-dev
# 替换为你的实际值
ACCESS_KEY_ID="your-access-key-id"
ACCESS_KEY_SECRET="your-access-key-secret"
BUCKET_NAME="your-bucket"
OSS_ENDPOINT="oss-cn-hangzhou.aliyuncs.com"
DATE=$(date -u +"%a, %d %b %Y %H:%M:%S GMT")

# 构造 CanonicalizedResource
CANONICALIZED_RESOURCE="/${BUCKET_NAME}/"

# 构造签名字符串
STRING_TO_SIGN="GET\n\n\n${DATE}\n${CANONICALIZED_RESOURCE}"

# 生成签名(需要安装 openssl)
SIGNATURE=$(echo -en "$STRING_TO_SIGN" | openssl sha1 -hmac "$ACCESS_KEY_SECRET" -binary | base64)

# 发送请求
curl -v "https://lanhuli-file.oss-cn-hongkong.aliyuncs.com/" \
  -H "Authorization: OSS Lxxxxxxxxxxxx72:" \
  -H "Date: $DATE"
// 测试 OSS 配置的极简 Demo (可直接在 Workers 运行)
export default {
  async fetch(request, env) {
    try {
      // ==================== 配置区域 ====================
      const ACCESS_KEY_ID = env.ACCESS_KEY_ID;     // 从环境变量读取
      const ACCESS_KEY_SECRET = env.ACCESS_KEY_SECRET;
      const BUCKET_NAME = env.BUCKET_NAME || "lanhuli-file";  // 默认桶名
      const OSS_ENDPOINT = "oss-cn-hongkong.aliyuncs.com";   // 替换为你的 Region
      // =================================================

      // 生成签名(精简版,仅用于测试)
      async function signRequest() {
        const now = new Date().toUTCString();
        const stringToSign = `GET\n\n\n${now}\n/${BUCKET_NAME}/`;
        const encoder = new TextEncoder();
        const secretKey = encoder.encode(ACCESS_KEY_SECRET);
        const signature = await crypto.subtle.sign(
          'HMAC',
          await crypto.subtle.importKey('raw', secretKey, { name: 'HMAC', hash: 'SHA-1' }, false, ['sign']),
          encoder.encode(stringToSign)
        );
        return `OSS ${ACCESS_KEY_ID}:${btoa(String.fromCharCode(...new Uint8Array(signature))}`;
      }

      // 发起测试请求(列出最多1个对象)
      const signature = await signRequest();
      const testUrl = `https://${BUCKET_NAME}.${OSS_ENDPOINT}/?max-keys=1`;
      const response = await fetch(testUrl, {
        headers: {
          'Authorization': signature,
          'Date': new Date().toUTCString(),
          'Host': `${BUCKET_NAME}.${OSS_ENDPOINT}`
        }
      });

      // 解析响应
      if (!response.ok) {
        const errorText = await response.text();
        throw new Error(`OSS 响应异常: HTTP ${response.status} - ${errorText}`);
      }

      // 返回测试结果
      return new Response(`
        ✅ OSS 配置测试通过!
        --------------------------
        Bucket: ${BUCKET_NAME}
        Endpoint: ${OSS_ENDPOINT}
        请求URL: ${testUrl}
      `, { headers: { 'Content-Type': 'text/plain' } });

    } catch (err) {
      // 返回详细错误信息
      return new Response(`
        ❌ OSS 配置测试失败
        --------------------------
        错误信息: ${err.message}
        
        排查步骤:
        1. 检查 AccessKey 是否有 oss:ListObjects 权限
        2. 确认 Bucket 名称和 Region 正确
        3. 确保 Bucket 存在且未设置为私有
      `, { headers: { 'Content-Type': 'text/plain' } });
    }
  }
};