没想到学校的网络中心居然不是干吃饭的,偶尔还会干点像用nmap啥的查开放端口和进行弱密码攻击测试的事的。上月底好像说要求托管的服务器要升级到最新的OpenSSH以及OpenSSL修复一些CVE漏洞(依稀记得是scp的提权漏洞啥的?)。不过2202年了谁还用scp呢,主流应该还是sftp和rsync吧。
既然被叫到了,那开搞就是了。
没想到学校的网络中心居然不是干吃饭的,偶尔还会干点像用nmap啥的查开放端口和进行弱密码攻击测试的事的。上月底好像说要求托管的服务器要升级到最新的OpenSSH以及OpenSSL修复一些CVE漏洞(依稀记得是scp的提权漏洞啥的?)。不过2202年了谁还用scp呢,主流应该还是sftp和rsync吧。
既然被叫到了,那开搞就是了。
久仰这篇论文大名,终于找到一个空闲时间好好看了一遍。论文名是Towards the Automatic Anime Characters Creation with Generative Adversarial Networks,复旦大佬发表在Comiket 92(2017年夏)的一篇论文。 简直就是CM中独树一帜的清流。 可惜这几年一直受疫情影响,没有机会亲身体验一次CM,也不知道以后还有没有机会。
其实嘛,也并不算复杂,走的是传统GAN那一套流程。Generator Network的输入分为两部分,一部分是128维的random input,另一部分是34维的标签,用于控制生成图像的人物形象(比如白毛、红瞳啥的);用的pixel shuffler升分辨率,也算是GAN的传统艺能了;输出是128×128的图片。Discriminator Network主要有两个任务,一个是判别图片的真假(是否由generator生成),另一个任务是判别人物形象,最终的loss由这两个loss加权而成。
参考的一个tensorflow的实现代码,随便Google出来的: https://github.com/ctwxdd/Tensorflow-ACGAN-Anime-Generation
代码其实也不难理解,不过跟论文还是有点区别的:noise input是100维度,generator输出的图片是96×96大小,发色分为12类,眼睛颜色11类,加起来少于原来的34类。数据预处理用到了数据集增广,包括水平增广、顺时针/逆时针旋转5°(因为旋转会带来黑边,因此对旋转后的图片先缩放为110×110再裁剪回96×96)。
即使如此,跑起来还是挺费资源的。内存直接32G起步,显存8.6G。用2080 Ti单卡跑的训练,速度还过得去,一天216k step,所以跑满1m step大概5天就好了,外加一顿外卖的电费。

跑到一半,老黄突然升级驱动导致服务器的nvidia-smi失效了,虽然不影响当前的训练,但是新开的进程都没办法跑gpu了,于是乎只能掐掉重启一遍服务器了。最后大概跑了722k个step,整个训练流程每200个step采样一次generator生成的图片,合并之后,得到一个将近2分钟的延时,还可以看着乐一乐。前半部分看着还好,后半部分已经有严重的mode collapse了,也是传统GAN的老毛病了。
这么一想,好久(大概有两年前了吧)之前就跑过老黄开源的StyleGAN,随机生成512×512的动漫头像,效果比这强太多了:

控制人物形象最大的问题还是数据集,尤其是与人物形象有关的label……上面这个的训练集是pixiv日榜的图片(用自己另外训练的Faster RCNN识别网络anime-face-detector进行头像识别与裁剪的),P站虽然也提供tag,但是tag的类型相对比较少,最常见的tag类型有:人物的角色名称、出处,与角色的形象特征(还是比如白毛、红瞳啥的)直接相关的tag一般是不会加上去的,所以也当不了label用。这么一想,怕不是得爬danbooru才行,这个tag相对比较全。
/etc/apache2/apache2.conf中:1 | <Directory /var/www/> |
Indexes,改为:1 | <Directory /var/www/> |
sudo a2enmod dav dav_fs auth_digest/var/www/webdav,我喜欢直接访问html root,所以用的是一个symbol link:ln -s /var/www/webdav /var/www/html(这个叫啥来着……WebDAV alongside HTTP service?)/var/www/webdav-config,直接mkdir新建一个就行www-data:www-data/etc/apache2/sites-enabled/default-ssl.conf,添加WebDAV相关的配置:1 | Alias /webdav /var/www/webdav # 将WebDAV路径映射到/webdav下 |
touch /var/www/webdav-config/passwd && chown www-data:www-data /var/www/webdav-config/passwdhtdigest [auth_file] [realm_name] [user_name],如htdigest /var/www/webdav-config/passwd webdav user将名为user的用户添加到webdav realm中然后就可以在linux和windows挂载WebDAV分区了,Windows可以通过命令行添加:net use Z: \\[your_host]@SSL\webdav,或者直接在文件浏览器上面的“映射网络驱动器”添加。
这样,HTTP请求到/webdav目录时是需要身份验证的,而默认的HTTP请求(除了/webdav以外的URL)不需要认证直接访问。
7/8更新:多个WebDAV目录的配置
有时候,有些文件只是想单纯用服务器存着,方便跨设备浏览,但不想暴露到无认证的HTTP服务中。
有两种配置方式。一种是直接在apache2配置文件上直接添加第二个Directory,开启DAV(重复上述第6步的步骤);另外一种是用mount --bind挂载其他文件夹到当前WebDAV文件夹下的子文件夹中,比如cd /var/www/webdav && mkdir html && mount --bind /var/www/html /var/www/webdav/html(更常见的是写到/etc/fstab中进行开机挂载:/var/www/html /var/www/webdav/html none bind),则将HTTP根目录挂载到WebDAV的html子文件夹中,只有该文件夹里面的内容是可以通过非WebDAV协议的一般HTTP请求获得的,其他内容则都需要登录才能访问。
百度一下应该就有了,单纯记录一下。
比如文件夹的右键菜单:
1 | [HKEY_CLASSES_ROOT\Directory\shell\<名称>] |
在文件夹里面右键背景的选单:[HKEY_CLASSES_ROOT\Directory\Background]
正常来讲,当数据包到达Linux系统时,都会经过一个防火墙进行基于规则的匹配过滤,决定该数据包继续进行转发还是直接丢弃等。iptables则负责担任这个防火墙的角色。自顶向下讲,iptables包含了若干个表(如raw、mangle、nat表等等)和若干个chain(如PREROUTING、INPUT等),组成一个2维的关系表:
| 表/Chain | PREROUTING |
INPUT |
FORWARD |
OUTPUT |
POSTROUTING |
|---|---|---|---|---|---|
| (路由决策) | ✓ | ||||
raw |
✓ | ✓ | |||
| (连接跟踪) | ✓ | ✓ | |||
mangle |
✓ | ✓ | ✓ | ✓ | ✓ |
nat (DNAT) |
✓ | ✓ | |||
| (路由决策) | ✓ | ✓ | |||
filter |
✓ | ✓ | ✓ | ||
security |
✓ | ✓ | ✓ | ||
nat (SNAT) |
✓ | ✓ |
不同的chain根据数据包的来源或者去向分别进行匹配过滤,内置的chain包含:
PREROUTING:传入流量到达本地网络栈时触发(此时还没进行任何路由决策)INPUT:传入数据包经过路由决策后,目的地址为本机时触发FORWARD:传入数据包经过路由决策后,目的地址为其他主机时触发OUTPUT:本地流量进入本地网络栈时触发POSTROUTING:路由决策后的传出流量或转发流量将数据放置到网线前触发每个chain则包含若干个表对数据包进行过滤/修改,iptables的表大致可以分为以下几类:
filter:是否允许数据包继续转发到目的地址(还是丢弃)的表nat:进行源/目的地址转换(即网络地址转换,NAT)的表,源/目的地址转换分别对应上表的SNAT/DNATmangle:更改数据包的IP头字段或者标记数据包的表raw:将每个连接的数据流视为一个个独立数据包并对其进行标记的表(前三个表会受到iptables的连接跟踪机制影响,即只对连接的首个数据包起效)security:跟SELinux有关,没接触过因此,传入到本机的流量会依次经过PREROUTING下的raw、mangle、nat表,然后再经过INPUT下的mangle、filter、security和nat表。转发到其他主机的流量则经过PREROUTING、FORWARD和POSTROUTING这3个chain,本地的传出流量则是OUTPUT再到POSTROUTING。
每个表可以通过iptables -t <表类型> -L进行查看,如iptables -t nat -L,不指定的情况下是filter表。
iptables的规则首先进行匹配,匹配成功则执行该规则的动作。匹配的规则是非常灵活的,可以根据协议类型、源/目的地址、连接状态等进行匹配。而动作目标(target)则是规则触发时所执行的动作,由参数-j决定,主要有两类目标:终止目标和非终止目标。iptables会依次执行chain中的规则,直到遇到终止目标时返回,遇到非终止目标则会继续执行相应的规则(如跳转到某些子chain进行匹配)。
连接跟踪:将每个packet组成一系列的连接,并对其进行状态跟踪,状态有:
NEW:首个valid的TCP/UDP packet到达且并未关联任何已有连接ESTABLISHED:首个valid的反向响应RELATED:不属于已有连接但与已有连接相关的packet,如FTP协议中除了控制连接外,还有一个传输数据的连接,该连接则属于RELATEDINVALID:不属于已有连接且不能视为建立连接的packetUNTRACKED:见下SNAT、DNAT:源/目的地址经NAT改变后的虚拟状态raw表标记为NOTRACK会跳过该机制(即状态设为UNTRACKED)。
另外有一点值得一提的是POSTROUTING的target MASQUERADE,本质上相当于一个自动化的SNAT,不需要自己填写外部的IP地址,但相对地,该target则需要指定一个网卡。
上文提到了iptables的众多功能,但还有一点略过没讲的就是里面的路由决策部分。这一部分不是iptables的工作,而是ip route的工作(注:route命令与ip route相似,但现在更偏向于使用ip route)。
一般情况下,系统默认会有3个路由表,可以通过ip rule进行查看:
local:本机路由和广播的表,本地网络连接的路由将参考这个表main:用于传输数据的路由表,对应网卡的网络设置default:默认为空的路由表每个表中通常会包含若干个路由规则,可以通过ip route [show table <表名或表ID>]查看,不过这部分没怎么深入了解,以后有时间再看了。
iptables可以配合路由表一起使用,如在iptables的mangle表中执行了MARK的动作时,ip可以根据该mark执行不同路由表下的路由规则。举个例子:在iptables中设置了iptables -t mangle -A FORWARD -i eth1 -j MARK --set-mark 1以及在ip中设置了ip rule add fwmark 1 table 10时,在iptables标记为1的数据包会执行ip中路由表10下的规则。