先來簡單介紹一下apache ftp server吧,顧名思義這個是Apache下的一個東東,個人感覺還是很新的,到現在才是1.0.X,不過還是相信Apache的品牌效應,這個東東用起來還是很友善的,通過配置檔案可以對ftp服務相關參數進行靈活配置,能夠支援基于配置檔案和資料庫的兩種使用者權限管理,另外還支援SSL協定和數字證書機制。
下面是官網的簡單介紹:
The Apache FtpServer is a 100% pure Java FTP server. It's designed to be a complete and portable FTP server engine solution based on currently available open protocols. FtpServer can be run standalone as a Windows service or Unix/Linux daemon, or embedded into a Java application. We also provide support for integration within Spring applications and provide our releases as OSGi bundles.
接下來我就按三部分介紹apache ftp server的使用。
1. 獨立部署apache ftp server作為系統服務
2. 作為為window系統的服務
3. 結合spring配置嵌入我們自己的系統
注:因為Apache FTP Server名字寫起來太長,以下簡稱為AFS.
1. 獨立部署AFS
1.1 安裝AFS http://mina.apache.org/ftpserver/
我用的版本是1.0.4, 本文就以該版本為例。無需安裝下載下傳後直接解壓即可。
因為是純java編寫的程式,是以程式部分windows和linux,解壓後在程式的bin目錄下有這樣一系列的可執行檔案。其中ftpd.bat和ftpd.sh分别是windows平台和linux下的啟動指令。
1.2 啟動AFS
AFS啟動時可以指定使用的具體的配置檔案,例如:
bin/ftpd.bat res/conf/ftpd-typical.xml
如果未指定配置檔案,那麼會預設用自帶的res/conf/ftpd-full.xml檔案作為配置檔案。
到此為止,一個ftp server就已經運作起來了。
1.3 AFS的配置
1.3.1 AFS配置檔案詳解
以AFS自帶的配置檔案ftpd-full.xml為例加以介紹。ftpd-full.xml路徑為$AFS_HOME\res\conf\ftpd-full.xml.
檔案内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<server xmlns="http://mina.apache.org/ftpserver/spring/v1"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://mina.apache.org/ftpserver/spring/v1 http://mina.apache.org/ftpserver/ftpserver-1.0.xsd
"
id="myServer">
<!--
Use this section to define custom listeners, or to redefine the
default listener, aptly named "default"
-->
<listeners>
<nio-listener name="default" port="2222" implicit-ssl="true"
idle-timeout="60" local-address="1.2.3.4">
<ssl>
<keystore file="mykeystore.jks" password="secret"
key-password="otherSecret" />
<truststore file="mytruststore.jks" password="secret" />
</ssl>
<data-connection idle-timeout="60">
<active enabled="true" local-address="1.2.3.4" local-port="2323"
ip-check="true" />
<passive ports="123-125" address="1.2.3.4" external-address="1.2.3.4" />
</data-connection>
<blacklist>1.2.3.0/16, 1.2.4.0/16, 1.2.3.4</blacklist>
</nio-listener>
</listeners>
<!--
Use this section to define your Ftplets, they are configured like
regular Spring beans
-->
<ftplets>
<ftplet name="ftplet1">
<beans:bean class="org.apache.ftpserver.examples.MyFtplet">
<beans:property name="foo" value="123" />
</beans:bean>
</ftplet>
</ftplets>
<!-- The user manager, choose one -->
<file-user-manager file="users.properties"
encrypt-passwords="true" />
<!--<db-user-manager>
<data-source>
<beans:bean class="some.datasoure.class" />
</data-source>
<insert-user>INSERT INTO FTP_USER (userid, userpassword,
homedirectory, enableflag, writepermission, idletime, uploadrate,
downloadrate) VALUES ('{userid}', '{userpassword}',
'{homedirectory}',
{enableflag}, {writepermission}, {idletime},
{uploadrate},
{downloadrate})
</insert-user>
<update-user>UPDATE FTP_USER SET
userpassword='{userpassword}',homedirectory='{homedirectory}',enableflag={enableflag},writepermission={writepermission},idletime={idletime},uploadrate={uploadrate},downloadrate={downloadrate}
WHERE userid='{userid}'
</update-user>
<delete-user>DELETE FROM FTP_USER WHERE userid = '{userid}'
</delete-user>
<select-user>SELECT userid, userpassword, homedirectory,
enableflag, writepermission, idletime, uploadrate, downloadrate,
maxloginnumber, maxloginperip FROM
FTP_USER WHERE userid = '{userid}'
</select-user>
<select-all-users>SELECT userid FROM FTP_USER ORDER BY userid
</select-all-users>
<is-admin>SELECT userid FROM FTP_USER WHERE userid='{userid}'
AND
userid='admin'
</is-admin>
<authenticate>SELECT userpassword from FTP_USER WHERE
userid='{userid}'</authenticate>
</db-user-manager> -->
<!-- The file system -->
<native-filesystem case-insensitive="false"
create-home="true" />
<!--
Use this section to define custom commands. Custom commands can also
override already existing commands
-->
<commands use-default="false">
<command name="MYHELP">
<beans:bean class="org.apache.ftpserver.examples.MYHELP" />
</command>
</commands>
<!-- Define the available languages -->
<messages languages="se, no ,da" />
</server>
1.3.1.1 server的配置
這一部分在官網寫的很清楚,可以檢視http://mina.apache.org/ftpserver/configuration.html。在這裡本人憑借英語四級的水準鬥膽翻譯一下。
屬性 | 描述 | 必填 | 預設值 |
id | 配置的server在該XML檔案中的唯一辨別 | 是 | |
max-logins | 最大同時線上使用者數 | 否 | 10 |
max-anon-logins | 最大同時線上匿名使用者數 | 否 | 10 |
anon-enabled | 是否啟動匿名登入 | 否 | true |
max-login-failures | 最大登入失敗次數,達到該次數後連接配接自動斷開。 | 否 | 3 |
login-failure-delay | 失敗登入後連接配接延遲時間(以毫秒為機關)。防止惡意使用者暴力破解密碼。 | 否 | 500 |
1.3.1.2 listeners 配置
Listeners元件是負責在ftp server指定的端口上監聽client端建立連接配接和執行指令。一個AFS可以同時有多個listeners。Listeners以name屬性作為唯一辨別,預設的listener的name為”default”.
Attribute | Description | Required | Default value |
name | Listener名稱,如果設定listener名稱為“default”,那麼該listener的設定會覆寫預設的listner。 | 是 | |
port | Listener監聽的端口 | 否 | 21 |
local-address | Server 綁定的本地服務位址 | 否 | All available |
implicit-ssl | 是否實作SSL的支援 | 否 | false |
idle-timeout | 空閑連接配接保持連接配接狀态的時長(機關為秒). | 否 | 300 |
1.3.2 AFS權限控制
AFS的權限控制有兩種方式:檔案控制和資料庫控制。
1.3.2.1 檔案控制權限的配置
通過檔案控制隻需在server的配置檔案中添加以下配置
<file-user-manager file="users.properties" encrypt-passwords="true" />
其中users.properties檔案權限控制檔案,encrypt-passwords可以指定密碼存儲的方式,有效值包括“clear”(明文),“md5”,”salted”,這個salted不知道是什麼意思,應該和MD5類似吧,估計也是一種加密标準,而且官方鼓勵使用salted.
AFS在安裝時就提供了一個預設的users.properties檔案,配置項一目了然。
1.3.2.1 資料庫控制權限
資料庫對使用者的權限的管理與通過檔案類似,不同就是把對使用者的配置移到了資料庫的表裡面。而且AFS提供了建表的sql語句,檔案存放在res下的ftp-db.sql。
關于此處的相關配置可以參見上面的完成配置執行個體,該部分的需要配置insert-user,update-user,delete-user,select-user,select-all-users,is-admin,authenticate。一般情況下我們都會用我們不會單獨用AFS來增删改使用者,但是update-user、delete-user和insert-user一個都不能少,不然AFS啟動時校驗通不過。另外我們通常會希望AFS的使用者管理與我們的應用系統采用統一管理,也就是不再為AFS建立專用的使用者管理表,這時候我們可以通過修改select-user、is-admin、authenticate等配置項來完成。不要以為随便改寫查詢sql都可以哦,AFS在處理這幾個查詢時是通過類似rs.getString(列名)的形式獲得記錄的,也就是說無論我們怎麼修改sql,但是資料列名或者别名一定要和AFS提供的預設查詢語句比對上,不然會有無效列名的錯誤。
關于AFS的配置大概就這些,總的來說各個配置項還是很直覺的。現在我們就可以執行bin\ftpd.sh啟動AFS了。
2.作為window系統的服務
如果是在windows平台的話,AFS還可以注冊為windows的系統服務來運作。方法也很簡單,直接執行:
<yourhome>bin\service install
運作成功後,進到windows的服務管理視窗就可以看到我們新注冊的名為Apache FtpServer的服務了。當然服務名是可以指定的,隻需:
<yourhome>bin\service install <your服務名>
此時建立的服務名就為Apache Ftp Servef <你指定的服務名>
如果我們想注冊服務時用特定的配置檔案可以執行如下指令:
<yourhome>bin\service install <your服務名> <你需要執行的檔案路徑>
解除安裝已經注冊的windows服務隻需:
<yourhome>bin\service remove <your服務名(不輸入為預設)>
3.結合spring配置嵌入我們自己的系統
以上我們介紹的是獨立部署AFS,其實AFS還可以結合spring嵌入到我們的應用程式中。
修改web.xml檔案添加spring的相關配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
src目錄下建立spring配置檔案applicationContext-ftpserver.xml
配置方法與前面提到的server配置參數相同,隻是此時的server作為spring的一個bean來處理。格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
">
<description>ftpserver demo</description>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/etlui"/>
</bean>
<server xmlns="http://mina.apache.org/ftpserver/spring/v1"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://mina.apache.org/ftpserver/spring/v1 http://mina.apache.org/ftpserver/ftpserver-1.0.xsd"
id="demoserver"
max-logins="500"
anon-enabled="false"
max-anon-logins="123"
max-login-failures="124"
login-failure-delay="125">
--具體配置參數
</server>
<bean id="ctroller" class="com.harvey.ftpd.ServiceController" init-method="init">
<property name="server">
<ref bean="demoserver"/>
</property>
<property name="server2">
<ref bean="demoserver2"/>
</property>
</bean>
</beans>
其中ServiceController代碼如下:
public class ServiceController {
private FtpServer server = null;
public void init() {
try {
server.start();
} catch (FtpException e) {
e.printStackTrace();
}
System.out.println("system exit");
}
public FtpServer getServer() {
return server;
}
public void setServer(FtpServer server) {
this.server = server;
}
}
現在我們就可以将AFS納入到我們的應用程式的管理範疇之内。
另外再說些其他的,因為server作為spring的一個bean來處理,是以可以配置多個server,也就是為主機配置多個AFS server,雖然可以這樣的配置,但是覺得也沒有這種必要,隻是覺得好玩可以配一下。