好久没有写日志了,不知道该怎么去描述这段时间,当岁数已经到三十的时候,心理上首先就感觉有点老了,呵呵,其实我不想变老,我想一直都是一个年轻的小伙子。哈。

从春节到现在,每天都在被长辈们催促人生大事,伴随而来的就是安排的各种相亲活动。话说,第一次是我大舅给安排的一个女孩,23岁,哈,岁数挺小,个子挺高的,可惜不是我喜欢的类型。第二次,阿姨给安排了一个23岁的姑娘,依旧不是我喜欢的类型,感觉没有气质,不够优雅。女孩子应该有一点气质和优雅的,毕竟相亲是为了组建一个和谐的家庭,哈,抱歉,我用到了“和谐”这个词儿,似乎最近不是很受欢迎,扯远了,相亲这种事情绝对不能委屈自己,即便大海捞针,梦里寻她千百度,难度再高,也要选择一个正确的人,当然,我的意思并不是一定要十全十美,扪心自问,我又何尝是那样的。引用数学的一个概念,只要约等于1就可以了,各位看官明白我的意思吗?

自从有了摩托车,还是像以前一样,每天骑车上下班,方便了很多。到目前,车车已经跑了800公里,让我很满意,无论是穿梭于闹市的车流之中,还是高速航行,给我的感觉是很爽,不过呢,还是很怀念以前的越野车,不怕颠簸的路面,专走不寻常路,而现在只能乖乖的在柏油路面行驶,不过这样也好。还是一个孩子。

上月月底,好友郑也顺利的荣升爹地,喜得千金,前两天吃满月酒,还看到了他可爱的千金,长得蛮像他老婆的。看着好友们都已经当爹了,心理的感慨还是很多的。你说我不发愁,肯定是假的了。真的。

昨天还有很多感慨,今天却不知道要怎么写了。前些日子,Q的签名一直是今年要完成一件傻傻的事情,很多朋友就问,是结婚的事情吧。看来我太单纯了,大家都清楚我的想法。哈。即便没有老婆,也要告诉自己,要好好的生活,开心每一天,做自己想做的事情,不要亏待了自己。

有些事情就是需要想开的,想不开永远在心里都是一个难以打开的心结。回首往事,也许错的比对的多,把每一个错误当成一个包袱,那么我想心里即便有再大的空间,也只是一个堆满了包袱的阴暗的杂物房。不知道为什么,电脑里面一直存着葛爷的非诚勿扰,总是会去一遍又一遍的看,不是看葛爷怎么相亲,而是那一段北海道的片段,葛爷和乌桑的交情,乌桑开车回家的路上的泪水,葛爷和乌桑的对话,这些深深的引起了我的共鸣。据说,葛爷的非诚勿扰2正在拍摄中,很期待后作,希望能更加完美。

那天吃满月酒,好朋友们约定清明节假期去兰州附近郊游,我也打算好了,骑着车车上路,再当一次风尘仆仆的独行侠,潇洒地游走在城市的边缘。我记得,那年国庆节我们三个人骑车去卓尼,在一段坡度不大的路上,我们挥开双手,依靠平衡感掌握车车,畅快的呼吸每一口空气,回忆总是很美好,好想再有时间出去跑一趟,我的同事说想徒步去拉萨,我也好想骑着车车征服世界屋脊。我有美好的回忆,幸福的梦想,我还缺少什么呢?

过些日子,某好友的火锅店就要开张了,哈哈,大家说好一定要去捧场,并且以后要让他给我们免单,哈哈。这两个月tony两口子,小鱼,我,小袁我们经常在周末约,虽然我喝不了多少酒,但是依旧很愿意陪着他们高兴一会,话说我发现一婚的男人很吃香啊,就这三个月里面小袁已经领了四个不同的小青年了,太佩服他了。哈哈。不过1月的时候,我还是有一次喝翻了,我们在鼓歌酒吧,当天我心情也不是很好,反正我喝了很多很多,最后是从酒吧里面强捂着嘴跑出来的,之后就是“现场直播”了,那天小鱼也在,我那天也是哭得稀里哗啦的,仿佛所有的伤心神经都被刺激了。我就是这么一个性情的人。

说说工作吧,最近在朋友那儿工作,主要是给网吧维护,还是学习到了很多有用的东西,发现了RouterOS,这是一个很好的软路由OS,基于linux内核,功能强大,容量很小,可惜的就是此OS是一款付费软件,当然,还是可以从网上找到crack的版本。最近也一直被UDP FLOOD困扰,某网吧的网关服务器用的是Ubuntu系统,但是经常收到大量的udp校验和错误的包,我个人怀疑是一种FLOOD攻击,查阅了很多网吧,发现从系统上是没有办法防的,必须架设硬件防火墙。从目前有的平台上来看,CentOS和RouterOS都是网关服务器的绝佳平台,CentOS就是更灵活些,更适合作为服务器OS来用,相较于其他Linux版本来看。

老妈子很反对我在朋友单位上班,看来我还得换换。她总是希望我能在一个新的环境下工作,没有任何依靠,完全靠自己去努力,说回来还是对个人综合能力的考验,看我够不够水平。

WIN7的时代来了,你们准备好更新知识,接受它了吗?

我最近也很少登Q,觉得很无聊,打开电脑,也就是听歌,看美剧,电影,学习一些知识了。别让我把所有的话都说完,来日方长。

祝,各位节日快乐。嘿嘿。


RouterOS的限速和限制线程的脚本,作为备用。

ARP静态绑定

第一步,扫描IP
/tool
ip-scan interface=lan
lan是客户机所接的interface

执行一断时间后,记得Quit

第二步,ARP绑定

/ip arp
foreach i in=[find dynamic=yes] do={add copy-from=$i]}  

限线程脚本:

for aaa from 2 to 254 do={/ip firewall filter add chain=forward src-address=(192.168.0. . $aaa) protocol=tcp connection-limit=3,32 action=drop}  

限速脚本:

for aaa from 2 to 254 do={/queue simple add name=(queue . $aaa) dst-address=(192.168.0. . $aaa) limit-at=0/0 max-limit=2048/1024}  

说明:
脚本为一行不是两行;
aaa是变量,2 to 254是2~254,192.168.0. . $aaa是IP,上两句加起来是192.168.0.2~192.168.0.254的意思;
connection-limit=50是线程数这里为50;
max-limit=2000000/2000000是上行/下行;

使用:

WinBox-System-Scripts-+
Name(脚本名程)
Source(脚本)
OK-选择要运行的脚本-Run Script

查看:

限线程:WinBox-IP-Firewall-Filter Rules(看是否已经填加进来)
限速:WinBox-Queues-Simple Queues(看是否已经填加进来)

双网切换脚本:

cncdown

 / ip route  
 set [/ip route find comm=”CNC”] gateway 网通网关

cncup

 / ip route  
 set [/ip route find comm=”CNC”] gateway 网通网关

maindown

 / ip route  
 set [/ip route find comm=”main”] gateway 电信网关

mainup

 / ip route  
 set [/ip route find comm=”main”] gateway 电信网关

网络通断

 / tool netwatch  
 add host=电信网关 timeout=1000ms interval=10s up-script=mainup down-script=maindown \  
 comment="" disabled=no  
 add host=网通网关 timeout=1000ms interval=10s up-script=cncup down-script=cncdown \  
 comment="" disabled=no

端口映射:

首先用WINBOX进入ROUTEROS,端口映射

/ ip firewall nat  
 add chain=dstnat in-interface=pppoe-out1 protocol=tcp dst-port=80 action=dst-nat \  
 to-addresses=192.168.1.10 to-ports=80 \

in-interface:选择公网接口 dst-port:选择需映射的端口
to-addresses: 输入需映射的主机地址 to-ports:输入主机需映射的端口


以前听人说在Linux上能够查到一个很奇怪的月份,只是当时忘了那个特别的月份。今天在网上搜了一下,发现通过这个命令(月份)了解了一段人类文明历史。

cal 9 1752  

九月 1752
一 二 三 四 五 六 日
1 2 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30

我们发现1752年9月2日的后面竟然是14日,确实很奇怪,通过在网上搜索,找到了答案:

1582年2月,罗马教廷需要从1582 年10月中减去10天,因此1852年10月4日后面紧跟着就是15日。在意大利、西班牙等国家都这样处理了。其他天主教国家也很快跟着这么做了,但是新教国家不愿意修改,而且希腊等东正教国家直到20世纪初才修改,所以这个改革在英国及其殖民地(包括美国)在1752年9月才被执行。这样1752年9月2日后面跟着的就是1752年9月14日。这就是为什么cal会生成上面输出的原因了。

Windows用户是没福气查到这个特别月份了,因为Windows的纪年范围只是1980-2099。呵呵。

1752年-九月迷题

1752年9月为什么少了11天?还是通过计算某天相对于元年元月1日(1/1/1)的天数,然后再计算星期,可是算来算去就是不准,突然发现1752年9月少了11天!! 我们知道,地球环绕太阳转动的周期是365.2422天,而早先人们所使用的儒略历中,因为每4年加进了1个闰日,即2月29日,所以平均下来,每一个儒略年为365.25天。可千万不要小看了这0.0078天(约11分14秒)的差别。一两年还无所谓,甚至十年二十年也过得去,可是几百年积累下来就非同小可了。

1752年-难解的题

事实上,在13世纪时,儒略年比实际的天象已经超出了8天,春分日竟然变成了3月13日,而天文学上规定应当是3月21日。当时杰出的思想家、科学家、哲学家罗吉尔·培根,特意于1263年致信罗马教皇乌尔班四世,敦促他们研究解决这个大问题(当时的制历权在教会)。可谁也没有想到,这个看似简单的问题却难倒了教廷,一直拖了三百多年,致使误差进一步扩大到10天。直到1582年,格里果里十三世教皇才同意了一位业余天文学家的方案,颁发了改儒略历为格里历的法令,其实,改变的实质主要有二:即在当年扣除多余的10天,具体说来说是把1582年10月4日(星期四)后面的那一天,作为10月15日星期五(本应是10月5日星期五);今后凡不能被400整除的世纪年,如1700年、1800年、1900年等不再作闰年,只有如1600年、2000年等那样可以被400除尽的年份才仍用闰年。这实际意味着在每400年中加了397个闰日,比原先少了整整3天,也说是说,在新的格里历中,一年长度平均是365.2425天,这与实际年长只差25.9秒,足可保证在二三千年内不出差错。

现行的公历是格利戈里历法,这个历法的是1582年教皇格利戈里根据恺撒大帝引进的算法改进的。它采用的是闰年制也就是现行的制度,不过有一个需要注意的地方就是,这个历法并不是连续的,中间缺少了11天。1752年9月2日之后的那一天并不是1752年9月3日,而是1752年9月14日。也就是说,从1752年9月3日到1752年9月13日的11天并不存在。抹掉这11天是由英国议会做出的决定。所以要计算某年每个月的天数的,除了要考虑是否是闰年以外,还要考虑1752年的9月。


近来安装了chrome,当使用扩展程序,安装google的官方扩展程序时,总是出现错误提示:

错误 101 (net::ERRCONNECTIONRESET):未知错误

在网上搜集了一下解决办法:

修改hosts文件,在C:\Windows\System32\Drivers\Etc\hosts加这么几行:

74.125.39.99 clients2.google.com  
74.125.39.99 chrome.google.com  
 74.125.39.99 tools.google.com  
 2001:4860:8004::89 www.google.com  
 2001:4860:8004::89 images.google.com  
 2001:4860:8004::89 video.google.com  
 2001:4860:8004::89 news.google.com  
 2001:4860:8004::89 www.google.com.hk  
 2001:4860:8004::89 images.google.com.hk  
 2001:4860:8004::89 video.google.com.hk  
 2001:4860:8004::89 news.google.com.hk

问题解决.如果你的系统是Vista或Win7,有6to4隧道服务(默认打开),可以直接使用我说的方法,不需要有IPV6接入。

提示:编辑时,最好使用editplus这样的专业的文本文件来编辑,保存时不要加扩展名


This document describes how to install a Proftpd server that uses virtual users from a MySQL database instead of real system users. This is much more performant and allows to have thousands of ftp users on a single machine. In addition to that I will show the use of quota with this setup.

For the administration of the MySQL database you can use web based tools like phpMyAdmin which will also be installed in this howto. phpMyAdmin is a comfortable graphical interface which means you do not have to mess around with the command line.

This tutorial is based on Ubuntu 9.10. You should already have set up a basic Ubuntu 9.10 server system.

This howto is meant as a practical guide; it does not cover the theoretical backgrounds. They are treated in a lot of other documents in the web.

This document comes without warranty of any kind! I want to say that this is not the only way of setting up such a system. There are many ways of achieving this goal but this is the way I take. I do not issue any guarantee that this will work for you!

1 Preliminary Note

In this tutorial I use the hostname server1.example.com with the IP address 192.168.0.100. These settings might differ for you, so you have to replace them where appropriate.

Make sure that you are logged in as root:
lang=”bash”>sudo su

1.1 Change The Default Shell

/bin/sh is a symlink to /bin/dash, however we need /bin/bash, not /bin/dash. Therefore we do this:

dpkg-reconfigure dash  

Install dash as /bin/sh? <– No

1.2 Disable AppArmor

AppArmor is a security extension (similar to SELinux) that should provide extended security. In my opinion you don’t need it to configure a secure system, and it usually causes more problems than advantages (think of it after you have done a week of trouble-shooting because some service wasn’t working as expected, and then you find out that everything was ok, only AppArmor was causing the problem). Therefore I disable it.

We can disable it like this:

/etc/init.d/apparmor stop  
update-rc.d -f apparmor remove  
aptitude remove apparmor apparmor-utils  

2 Install MySQL And phpMyAdmin

This can all be installed with one single command:

aptitude install mysql-server mysql-client phpmyadmin apache2  

You will be asked to provide a password for the MySQL root user – this password is valid for the user root@localhost as well as root@server1.example.com, so we don't have to specify a MySQL root password manually later on:

New password for the MySQL “root” user:* <– yourrootsqlpassword  
Repeat password for the MySQL “root” user:* <– yourrootsqlpassword  

In addition to this, you will see the following questions:

Web server to reconfigure automatically: <– apache2
Configure database for phpmyadmin with dbconfig-common? <– No

3 Install Proftpd With MySQL Support

For Ubuntu there is a pre-configured proftpd-mod-mysql package available. Install it as a standalone daemon like this:

aptitude install proftpd-mod-mysql  

You will be asked the following question:

*Run proftpd:* <– standalone

Then we create an ftp group (ftpgroup) and user (ftpuser) that all our virtual users will be mapped to. Replace the group- and userid 2001 with a number that is free on your system:

groupadd -g 2001 ftpgroup  
useradd -u 2001 -s /bin/false -d /bin/null -c "proftpd user" -g ftpgroup ftpuser  

4 Create The MySQL Database For Proftpd

Now we create a database called ftp and a MySQL user named proftpd which the proftpd daemon will use later on to connect to the ftp database:

mysql -u root -p  
CREATE DATABASE ftp;  
GRANT SELECT, INSERT, UPDATE, DELETE ON ftp.* TO 'proftpd'@'localhost' IDENTIFIED BY 'password';  
GRANT SELECT, INSERT, UPDATE, DELETE ON ftp.* TO 'proftpd'@'localhost.localdomain' IDENTIFIED BY 'password';  
FLUSH PRIVILEGES;  

Replace the string password with whatever password you want to use for the MySQL user proftpd. Still on the MySQL shell, we create the database tables we need:

USE ftp;  
CREATE TABLE ftpgroup (  
 groupname varchar(16) NOT NULL default '',  
 gid smallint(6) NOT NULL default '5500',  
 members varchar(16) NOT NULL default ”,  
 KEY groupname (groupname)  
 ) TYPE=MyISAM COMMENT='ProFTP group table';

CREATE TABLE ftpquotalimits (  
 name varchar(30) default NULL,  
 quota_type enum('user','group','class','all') NOT NULL default 'user',  
 per_session enum('false','true') NOT NULL default 'false',  
 limit_type enum('soft','hard') NOT NULL default 'soft',  
 bytes_in_avail bigint(20) unsigned NOT NULL default '0',  
 bytes_out_avail bigint(20) unsigned NOT NULL default '0',  
 bytes_xfer_avail bigint(20) unsigned NOT NULL default '0',  
 files_in_avail int(10) unsigned NOT NULL default '0',  
 files_out_avail int(10) unsigned NOT NULL default '0',  
 files_xfer_avail int(10) unsigned NOT NULL default '0'  
 ) TYPE=MyISAM;

CREATE TABLE ftpquotatallies (  
 name varchar(30) NOT NULL default '',  
 quota_type enum('user','group','class','all') NOT NULL default 'user',  
 bytes_in_used bigint(20) unsigned NOT NULL default '0',  
 bytes_out_used bigint(20) unsigned NOT NULL default '0',  
 bytes_xfer_used bigint(20) unsigned NOT NULL default '0',  
 files_in_used int(10) unsigned NOT NULL default '0',  
 files_out_used int(10) unsigned NOT NULL default '0',  
 files_xfer_used int(10) unsigned NOT NULL default '0'  
 ) TYPE=MyISAM;

CREATE TABLE ftpuser (  
 id int(10) unsigned NOT NULL auto_increment,  
 userid varchar(32) NOT NULL default '',  
 passwd varchar(32) NOT NULL default '',  
 uid smallint(6) NOT NULL default '5500',  
 gid smallint(6) NOT NULL default '5500',  
 homedir varchar(255) NOT NULL default '',  
 shell varchar(16) NOT NULL default '/sbin/nologin',  
 count int(11) NOT NULL default '0',  
 accessed datetime NOT NULL default '0000-00-00 00:00:00',  
 modified datetime NOT NULL default '0000-00-00 00:00:00',  
 PRIMARY KEY (id),  
 UNIQUE KEY userid (userid)  
 ) TYPE=MyISAM COMMENT='ProFTP user table';

quit;  

As you may have noticed, with the quit; command we have left the MySQL shell and are back on the Linux shell.

BTW, (I’m assuming that the hostname of your ftp server system is server1.example.com) you can access phpMyAdmin under http://server1.example.com/phpmyadmin/ (you can use the IP address instead of server1.example.com) in a browser and log in as proftpd. Then you can have a look at the database. Later on you can use phpMyAdmin to manage your Proftpd server.

5 Configure Proftpd

Open /etc/proftpd/modules.conf

vi /etc/proftpd/modules.conf  

… and enable the following three modules:

# Install proftpd-mod-mysql or proftpd-mod-pgsql to use this  
 LoadModule mod_sql.c  
 […]  
 # Install proftpd-mod-mysql to use this  
 LoadModule mod_sql_mysql.c  
 […]  
 # Install proftpd-mod-pgsql or proftpd-mod-mysql to use this  
 LoadModule mod_quotatab_sql.c

Then open /etc/proftpd/proftpd.conf and comment out the following lines:

vi /etc/proftpd/proftpd.conf  
#  
#QuotaEngine off  
#
Further down in the file, add the following lines:  
 #  
 # Alternative authentication frameworks  
 #  
 #Include /etc/proftpd/ldap.conf  
 #Include /etc/proftpd/sql.conf
DefaultRoot ~

SQLBackend mysql  
 # The passwords in MySQL are encrypted using CRYPT  
 SQLAuthTypes Plaintext Crypt  
 SQLAuthenticate users groups

# used to connect to the database  
 # databasename@host database_user user_password  
 SQLConnectInfo ftp@localhost proftpd password

# Here we tell ProFTPd the names of the database columns in the “usertable”  
 # we want it to interact with. Match the names with those in the db  
 SQLUserInfo ftpuser userid passwd uid gid homedir shell

# Here we tell ProFTPd the names of the database columns in the “grouptable”  
 # we want it to interact with. Again the names match with those in the db  
 SQLGroupInfo ftpgroup groupname gid members

# set min UID and GID – otherwise these are 999 each  
 SQLMinID 500

# create a user’s home directory on demand if it doesn’t exist  
 CreateHome on

# Update count every time user logs in  
 SQLLog PASS updatecount  
 SQLNamedQuery updatecount UPDATE “count=count+1, accessed=now() WHERE userid=’%u'” ftpuser

# Update modified everytime user uploads or deletes a file  
 SQLLog STOR,DELE modified  
 SQLNamedQuery modified UPDATE “modified=now() WHERE userid=’%u'” ftpuser

# User quotas  
 # ===========  
 QuotaEngine on  
 QuotaDirectoryTally on  
 QuotaDisplayUnits Mb  
 QuotaShowQuotas on

SQLNamedQuery get-quota-limit SELECT “name, quota_type, per_session, limit_type, bytes_in_avail, bytes_out_avail, bytes_xfer_avail, files_in_avail, files_out_avail, files_xfer_avail FROM ftpquotalimits WHERE name = ‘%{0}’ AND quota_type = ‘%{1}'”

SQLNamedQuery get-quota-tally SELECT “name, quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used, files_in_used, files_out_used, files_xfer_used FROM ftpquotatallies WHERE name = ‘%{0}’ AND quota_type = ‘%{1}'”

SQLNamedQuery update-quota-tally UPDATE “bytes_in_used = bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, files_xfer_used = files_xfer_used + %{5} WHERE name = ‘%{6}’ AND quota_type = ‘%{7}'” ftpquotatallies

SQLNamedQuery insert-quota-tally INSERT “%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}” ftpquotatallies

QuotaLimitTable sql:/get-quota-limit  
 QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally

RootLogin off  
 RequireValidShell off

Make sure that you replace the string password with the real password for the MySQL user proftpd in the line SQLConnectInfo!

Then restart Proftpd:

/etc/init.d/proftpd restart

6 Populate The Database And Test

To populate the database you can use the MySQL shell:

mysql -u root -p  
USE ftp;  

First we create an entry in the table ftpgroup. It contains the groupname, the groupid and the username of the ftp group/user we created at the end of step two (replace the groupid appropriately if you use another one than 2001):

INSERT INTO `ftpgroup` (`groupname`, `gid`, `members`) VALUES ('ftpgroup', 2001, 'ftpuser');  

Now we are done with the table ftpgroup. We do not have to create further entries here. Whenever you create a new virtual ftp user, you do this in the tables ftpquotalimits and ftpuser. So let us create our first user exampleuser with a quota of 15MB and the password secret (we are still in the MySQL shell):

INSERT INTO `ftpquotalimits` (`name`, `quota_type`, `per_session`, `limit_type`, `bytes_in_avail`, `bytes_out_avail`, `bytes_xfer_avail`, `files_in_avail`, `files_out_avail`, `files_xfer_avail`) VALUES ('exampleuser', 'user', 'true', 'hard', 15728640, 0, 0, 0, 0, 0);

INSERT INTO `ftpuser` (`id`, `userid`, `passwd`, `uid`, `gid`, `homedir`, `shell`, `count`, `accessed`, `modified`) VALUES (1, 'exampleuser', 'secret', 2001, 2001, '/home/www.example.com', '/sbin/nologin', 0, '', '');

quit;  

(Do not forget to replace the groud- and userid 2001 appropriately in the last INSERT statement if you are using other values than in this tutorial!)

Now open your FTP client program on your work station (something like FileZilla, WS_FTP, SmartFTP or gFTP) and try to connect. As hostname you use server1.example.com (or the IP address of the system), the username is exampleuser, and the password is secret.

If you are able to connect – congratulations! If not, something went wrong.

Now, if you run
ls -l /home/

you should see that the directory /home/www.example.com (exampleuser’s home directory) has been automatically created, and it is owned by ftpuser and ftpgroup (the user/group we created at the end of step two):

*root@server1:~# ls -l /home/  
 total 12  
 drwxr-xr-x 2 administrator administrator 4096 2010-01-04 15:38 administrator  
 drwxr-xr-x 2 ftp nogroup 4096 2010-01-04 17:10 ftp  
 drwx------ 2 ftpuser ftpgroup 4096 2010-01-04 17:26 www.example.com  
 root@server1:~#*

7 Database Administration

For most people it is easier if they have a graphical front-end to MySQL; therefore you can also use phpMyAdmin (in this example under http://server1.example.com/phpmyadmin/) to administrate the ftp database.

Whenever you create a new user, you only have to create entries in the tables ftpquotalimits and ftpuser so I will explain the columns of these tables here:

ftpuser Table:
The important columns are these (the others are handled by MySQL or Proftpd automatically, so do not fill these manually!):

  • userid: The name of the virtual Proftpd user (e.g. exampleuser).
  • passwd: The unencrypted (i.e., clear-text) password of the user.
  • uid: The userid of the ftp user you created at the end of step two (e.g. 2001).
  • gid: The groupid of the ftp group you created at the end of step two (e.g. 2001).
  • homedir: The home directory of the virtual Proftpd user (e.g. /home/www.example.com). If it does not exist, it will be created when the new user logs in the first time via FTP. The virtual user will be jailed into this home directory, i.e., he cannot access other directories outside his home directory.
  • shell: It is ok if you fill in /sbin/nologin here by default.

ftpquotalimits Table:

The important columns are these (the others are handled by MySQL or Proftpd automatically, so do not fill these manually!):

  • name: The name of the virtual Proftpd user (e.g. exampleuser).
  • quota_type: user or group. Normally, we use user here.
  • per_session: true or false. true means the quota limits are valid only for a session. For example, if the user has a quota of 15 MB, and he has uploaded 15 MB during the current session, then he cannot upload anything more. But if he logs out and in again, he again has 15 MB available. false means, that the user has 15 MB, no matter if he logs out and in again.
  • limit_type: hard or soft. A hard quota limit is a never-to-exceed limit, while a soft quota can be temporarily exceeded. Normally you use hard here.
  • bytesinavail: Upload limit in bytes (e.g. 15728640 for 15 MB). 0 means unlimited.
  • bytesoutavail: Download limit in bytes. 0 means unlimited.
  • bytesxferavail: Transfer limit in bytes. The sum of uploads and downloads a user is allowed to do. 0 means unlimited.
  • filesinavail: Upload limit in files. 0 means unlimited.
  • filesoutavail: Download limit in files. 0 means unlimited.
  • filesxferavail: Tranfer limit in files. 0 means unlimited.

The ftpquotatallies table is used by Proftpd internally to manage quotas so you do not have to make entries there!

8 Anonymous FTP

If you want to create an anonymous ftp account (an ftp account that everybody can login to without a password), you can do it like this:

First we create a user and group with the name anonymous_ftp. The user has the home directory /home/anonymous_ftp:

groupadd -g 2002 anonymous_ftp  
useradd -u 2002 -s /bin/false -d /home/anonymous_ftp -m -c “Anonymous FTP User” -g anonymous_ftp anonymous_ftp  

(Replace 2002 with a group-/userid that is free on your system.)

A few files beginning with a . have been created by the last command (useradd) in the /home/anonymous_ftp directory. We don’t need them, so we delete them:

cd /home/anonymous_ftp  
rm -f .bash_logout  
rm -f .profile  
rm -f .bashrc  

Then we create the directory /home/anonymous_ftp/incoming which will allow anonymous users to upload files:

mkdir /home/anonymous_ftp/incoming  
chown anonymous_ftp:nogroup /home/anonymous_ftp/incoming  

And finally, open /etc/proftpd/proftpd.conf and append the following directives to it:

vi /etc/proftpd/proftpd.conf  
User anonymous_ftp  
Group nogroup  
 # We want clients to be able to login with “anonymous” as well as “ftp”  
UserAlias anonymous anonymous_ftp  
 # Cosmetic changes, all files belongs to ftp user  
DirFakeUser on anonymous_ftp  
DirFakeGroup on anonymous_ftp

RequireValidShell off

# Limit the maximum number of anonymous logins  
 MaxClients 10

# We want ‘welcome.msg’ displayed at login, and ‘.message’ displayed  
# in each newly chdired directory.  
 DisplayLogin welcome.msg  
 DisplayChdir .message

# Limit WRITE everywhere in the anonymous chroot
DenyAll

# Uncomment this if you’re brave.
# Umask 022 is a good standard umask to prevent new files and dirs  
# (second parm) from being group and world writable.  
Umask 022 022

DenyAll

AllowAll  

Finally restart Proftpd:

/etc/init.d/proftpd restart

Now anonymous users can login, and they can download files from /home/anonymous_ftp, but uploads are limited to /home/anonymous_ftp/incoming (and once a file is uploaded into /home/anonymous_ftp/incoming, it cannot be read nor downloaded from there; the server admin has to move it into /home/anonymous_ftp first to make it available to others).

(Please note: You can only have one anonymous ftp account per IP address!)