FTP ASCII 上传失效
近期在进行AIX到Linux迁移,发现从windows终端ftp时,客户端设置ASCII传输模式, 服务端并不能自动转换换行符号,脚本出现^M,需要手工删除。 Linux环境为RedHat7.3+vsftpd(3.0.2),vsftpd.conf中ascii_download_enable/ascii_upload_enable 注释掉了,未开启.
RFC959中的ASCII TYPE
| |
使用ASCII模式进行ftp传输时, 会把发送端本地NewLine编码, 转为NVT-ASCII格式( ), 接收端收到后,再转为本地NewLine编码。
如果window编写本有用过ASCII模式
回车与换行
起源
早在19世纪中期,电报使用的摩尔斯编码使用 AA (▄▄▄▄▄▄▄▄▄▄▄▄▄▄) 表示新行的开始。
CR+LF在的电传打字机上使用,典型的是Teletype Model 33,将换行设置为两个字符的原因是打印头不能及时的从最右边返回到下一行的开头, 在CR之后,打印头正在移动到下一行的头部过程中,如果这时收到字符,会将页面中间污损,解决方案是将换行设置为两个字符:CR: 将托架移动到第一列, LF,纸张上移一行。实际上,有时还需要增加额外的无关字符,如CR或NUL能被忽略,而且给打印头移动到下一行最左端预留时间。
CR+LF在Teletype机器上使用,后续出现的DEC, CP/M也使用了这种惯例,1981年,MS-DOS采用CP/M的CR+LF以便兼容,后续windows采用此编码。
Multics操作系统于1964年开始开发,仅使用LF作为其换行符。而后续出现的Unix跟随了Multic的实践。
表示
关于换行-NewLine,不同操作系统存在差异 (ASCII),下面较常见的
| 操作系统 | 编码 | 符号 | Hex |
|---|---|---|---|
| Windows | ASCII | <CR><LF> | 0D 0A |
| Unix/Linux | ASCII | <LF> | 0A |
| Mac | ASCII | <CR> | 0D |
来个更全的信息
| Operating system | Character encoding | Abbreviation | hex value | dec value | Escape sequence |
|---|---|---|---|---|---|
| Multics, Unix and Unix-like systems (Linux, macOS, FreeBSD, AIX, Xenix, etc.), BeOS, Amiga, RISC OS, and others | ASCII | LF | OA | 10 | \n |
| Atari TOS, Microsoft Windows, DOS (MS-DOS, PC DOS, etc.), DEC TOPS-10, RT-11, CP/M, MP/M, OS/2, Symbian OS, Palm OS, Amstrad CPC, and most other early non-Unix and non-IBM operating systems | ASCII | CF LF | 0D OA | 13 10 | \r\n |
| Commodore 8-bit machines (C64, C128), Acorn BBC, ZX Spectrum, TRS-80, Apple II family, Oberon, the classic Mac OS, MIT Lisp Machine and OS-9 | ASCII | CR | OD | 13 | \r |
| QNX pre-POSIX implementation (version < 4) | ASCII | RS | 1E | 30 | |
| Acorn BBC and RISC OS spooled text output. | ASCII | LF CR | 0A 0D | 10 13 | \n\r |
| Acorn BBC and RISC OS spooled text output. | ASCII | LF CR | 0A 0D | 10 13 | \n\r |
| Atari 8-bit machines | ATASCII | 9B | 155 | ||
| IBM mainframe systems, including z/OS (OS/390) and i5/OS (OS/400) | EBCDIC | NL | 15 | 21 | \025 |
| ZX80 and ZX81 (Home computers from Sinclair Research Ltd) | used a specific non-ASCII character set | NEWLINE | 76 | 118 |
FTP ASCII模式的使用
正是由于ftp服务端可以默认不支持ASCII方式,会给我们在使用是带来一下困扰,以vsftpd为例看下,下面是配置文件 vsftpd.conf
| |
由于支持ASCII模式会触发某些ftp服务器上Dos攻击漏洞,出于安全考虑,服务端关闭了ASCII支持,但是客户端如果请求 ASCII模式,服务端将忽略,并返回客户端:200 Switching to ASCII mode., 所以这种情况下客户端不知道服务端已经拒绝了这种传输模式,这种情况下会出现一些问题;
下面以上传一个内容为"test[换行]“的文件到ftp服务器(vsftpd),看下ASCII的工作模式下,文件内容的变化
- vsftpd
ascii_download_enable,ascii_upload_enable设置为YES
| 客户端平台 | 客户端文件内容 | 文件传输过程中 | 文件落地服务端 |
|---|---|---|---|
| unix | test\n | test\r\n | test\n |
| windows | test\r\n | test\r\n | test\n |
- vsftpd
ascii_download_enable,ascii_upload_enable设置为NO
| 客户端平台 | 客户端文件内容 | 文件传输过程中 | 文件落地服务端 |
|---|---|---|---|
| unix | test\n | test\r\n | test\r\n |
| windows | test\r\n | test\r\n | test\r\n |
问题出现在如果传输一个不是本操作系统的换行符号的文件
- vsftpd
ascii_download_enable,ascii_upload_enable设置为YES
| 客户端平台 | 客户端文件内容 | 文件传输过程中 | 文件落地服务端 |
|---|---|---|---|
| unix+ftp | test\r\n | test\r\r\n | test\r\n |
由于支持ASCII模式,服务端还是会转为本地的换行符号<LF>
- vsftpd
ascii_download_enable,ascii_upload_enable设置为YES
| 客户端平台 | 客户端文件内容 | 文件传输过程中 | 文件落地服务端 |
|---|---|---|---|
| unix+ftp | test\r\n | test\r\r\n | test\r\r\n |
文件会多一个 <CR>将做为文件内容保留。反过来如果服务器存在一个文件包含<CR><CR><LF>传输过程中会将<CR>丢掉。
结论
实际应用中,统一使用BIN还是比较安全的。如果涉及脚本或者配置文件的上传出现^M,可以通过文本工具转化为UNIX格式后再使用BIN模式上传,或者文件上传后手工删除文件中的^M。
参考
How does ASCII upload and download work in vsftpd? Doesn’t it work backwards? 回车和换行 NewLine wiki RFC959