<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title><![CDATA[AdminsForum - aaPanel FTP, SFTP & File Transfer Guides]]></title>
		<link>https://adminsforum.com/</link>
		<description><![CDATA[AdminsForum - https://adminsforum.com]]></description>
		<pubDate>Thu, 15 Oct 2026 07:04:54 +0000</pubDate>
		<generator>MyBB</generator>
		<item>
			<title><![CDATA[Automatically Update the Pure-FTPd FTPS Certificate in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-automatically-update-the-pure-ftpd-ftps-certificate-in-aapanel</link>
			<pubDate>Tue, 13 Oct 2026 16:47:00 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-automatically-update-the-pure-ftpd-ftps-certificate-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">Renewing a website or mail certificate does not automatically update a separate Pure-FTPd PEM bundle.</span> If you manually copied a certificate for FTPS, the FTP service can keep using an older certificate after the original renews. This guide closes that gap using a checked deployment helper.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What this does</span><br />
The helper reads an <span style="font-weight: bold;" class="mycode_b">already renewed</span> certificate managed by aaPanel, validates it, and deploys the combined certificate/key bundle used by Pure-FTPd. It does not request a new certificate or replace the existing certificate-renewal mechanism. You must keep that original renewal working and monitor its result.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Confirm the source and destination</span><br />
In our lab the certificate belongs to <span style="font-weight: bold;" class="mycode_b">mail.adminslab.com</span>. Its source files are:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/panel/vhost/cert/mail.adminslab.com/fullchain.pem
/www/server/panel/vhost/cert/mail.adminslab.com/privkey.pem</code></div></div>Pure-FTPd uses <br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/etc/ssl/private/pure-ftpd.pem</code></div></div>Confirm your own hostname, certificate paths and service name first. Do not copy another site's private key or publish the key in a post. Keep the FTP bundle root-owned and readable only by root. Retain a private rollback copy and confirm provider-console access before changing the service.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Install the helper after reviewing it</span><br />
Save the following as <span style="font-weight: bold;" class="mycode_b">/usr/local/sbin/af-sync-ftps-certificate.py</span> using your authorized root session. The code below is the lab version. Adapt the hostname, source folder and private backup folder to your server before using it. It expects Python 3, OpenSSL, ss and systemctl, and the existing pure-ftpd.service.<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>#!/usr/bin/python3
"""Deploy an already-renewed aaPanel certificate to Pure-FTPd without exposing its key."""
import argparse,fcntl,hashlib,os,ssl,subprocess,tempfile
from pathlib import Path
parser=argparse.ArgumentParser();parser.add_argument('--dry-run',action='store_true');args=parser.parse_args()
if os.geteuid()!=0: raise SystemExit('Root required')
lock=open('/run/af-ftps-certificate-sync.lock','w');fcntl.flock(lock,fcntl.LOCK_EX|fcntl.LOCK_NB)
source=Path('/www/server/panel/vhost/cert/mail.adminslab.com');target=Path('/etc/ssl/private/pure-ftpd.pem')
cert=source/'fullchain.pem';key=source/'privkey.pem'
for p in [cert,key,target]:
 if not p.is_file() or p.is_symlink():raise SystemExit('Expected regular certificate file missing')
subprocess.run(['openssl','x509','-in',str(cert),'-noout','-checkend','604800'],check=True,stdout=subprocess.DEVNULL)
subprocess.run(['openssl','verify','-CApath','/etc/ssl/certs','-verify_hostname','mail.adminslab.com','-untrusted',str(cert),str(cert)],check=True,stdout=subprocess.DEVNULL)
bundle=cert.read_bytes().rstrip()+bytes([10])+key.read_bytes().rstrip()+bytes([10])
fd,name=tempfile.mkstemp(prefix='.af-ftps-',dir=str(target.parent));tmp=Path(name)
try:
 os.fchmod(fd,0o600)
 with os.fdopen(fd,'wb') as out:out.write(bundle);out.flush();os.fsync(out.fileno())
 context=ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER);context.load_cert_chain(str(tmp))
 old=target.read_bytes()
 if old==bundle:print('FTPS certificate already synchronized; no restart');raise SystemExit(0)
 if args.dry_run:print('DRY RUN PASS: chain, hostname, expiry and matching key validated; update required');raise SystemExit(0)
 sessions=subprocess.check_output(['ss','-Hnt','state','established','sport','=',':21'],text=True)
 if sessions.strip():raise SystemExit('Active FTP control session: deferred until next run')
 backup=Path('/root/af-hosting-batch-20261012/ftps-renewal-20261013');backup.mkdir(mode=0o700,parents=True,exist_ok=True)
 previous=backup/'previous-bundle.pem';previous.write_bytes(old);previous.chmod(0o600)
 os.replace(tmp,target);os.chmod(target,0o600)
 try:
  subprocess.run(['systemctl','restart','pure-ftpd.service'],check=True)
 except Exception:
  target.write_bytes(old);target.chmod(0o600);subprocess.run(['systemctl','restart','pure-ftpd.service'],check=False);raise
 print('FTPS certificate deployed; Pure-FTPd restarted')
finally:
 if tmp.exists():tmp.unlink()</code></div></div>Then set its ownership/permissions and run a dry check:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>chown root:root /usr/local/sbin/af-sync-ftps-certificate.py
chmod 700 /usr/local/sbin/af-sync-ftps-certificate.py
/usr/local/sbin/af-sync-ftps-certificate.py --dry-run</code></div></div>The helper checks the certificate chain and hostname, a seven-day remaining-validity margin, and that the key matches the certificate. If the existing bundle already matches, it exits without restarting FTP. If a control connection is active, a live deployment is deferred. A failure message needs investigation; do not bypass the validation just to make the job complete.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Deploy once and verify trusted FTPS</span><br />
Run the helper without --dry-run. When the source differs, it preserves the previous bundle privately, replaces the file with mode 600 and restarts Pure-FTPd. It attempts to restore the old bundle if the restart fails.<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/usr/local/sbin/af-sync-ftps-certificate.py</code></div></div>Reconnect using the certificate's hostname and explicit FTPS. Confirm certificate validation succeeds. Do not use an IP address as the hostname when the certificate covers a DNS name. Check an encrypted upload/download after a real renewal, not just the certificate's displayed expiration date.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=138" target="_blank" title="">ftps-sync-branded-20261013.jpg</a> (Size: 58.93 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Actual lab deployment: updated bundle, trusted TLS 1.3, then an unchanged second run with no restart.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Add the scheduled check</span><br />
Our lab uses a root-owned /etc/cron.d/af-ftps-certificate-sync file with:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SHELL=/bin/sh
PATH=/usr/sbin:/usr/bin:/sbin:/bin
17 * * * * root /usr/local/sbin/af-sync-ftps-certificate.py &gt;&gt; /var/log/af-ftps-certificate-sync.log 2&gt;&amp;1</code></div></div>This runs at minute 17 of each hour in the server's configured timezone. Use only one copy of the schedule; do not also create an identical panel task. Set the schedule file to root ownership and mode 644, and pre-create the log root-owned with mode 600. Check that the cron daemon is running. If you prefer aaPanel Cron, create the equivalent root Shell Script task and use the helper command, with private logging.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Monitor the complete renewal path</span><br />
Read the private log for validation errors, deferred sessions or a failed restart. Inspect source certificate expiration and the actual certificate presented by FTPS. Persistent FTP sessions can delay deployment; plan a maintenance window if that continues. The old backup bundle includes a private key and must remain private. Arrange suitable log retention and an alert route outside the server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Troubleshooting</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Source missing:</span> confirm the actual aaPanel certificate folder and that renewal produced files.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Chain/hostname check fails:</span> confirm the certificate covers the FTPS hostname and includes the necessary intermediate certificates.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Key mismatch:</span> use the key from the same certificate issuance; never guess or combine unrelated files.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Expiry margin fails:</span> repair the original renewal process before attempting deployment.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Active session deferred:</span> wait for transfers to finish; the next scheduled run can retry.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">FTP restart fails:</span> inspect the service configuration and restore the private previous bundle if required.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Verified scope</span><br />
The lab passed dry validation, live deployment, trusted FTPS TLS 1.3, an unchanged no-restart run, and cron-service/schedule checks. A future certificate issuance and a future automatic renewal have not yet occurred, so this is not a claim that the next renewal has already succeeded. The existing aaPanel certificate-renewal job was preserved.<br />
<br />
<a href="https://adminsforum.com/Thread-guide-enable-ftps-encryption-and-ssl-for-pure-ftpd-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Start with the FTPS setup guide</a>. Original helper and lab evidence: © AdminsForum.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">Renewing a website or mail certificate does not automatically update a separate Pure-FTPd PEM bundle.</span> If you manually copied a certificate for FTPS, the FTP service can keep using an older certificate after the original renews. This guide closes that gap using a checked deployment helper.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What this does</span><br />
The helper reads an <span style="font-weight: bold;" class="mycode_b">already renewed</span> certificate managed by aaPanel, validates it, and deploys the combined certificate/key bundle used by Pure-FTPd. It does not request a new certificate or replace the existing certificate-renewal mechanism. You must keep that original renewal working and monitor its result.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Confirm the source and destination</span><br />
In our lab the certificate belongs to <span style="font-weight: bold;" class="mycode_b">mail.adminslab.com</span>. Its source files are:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/panel/vhost/cert/mail.adminslab.com/fullchain.pem
/www/server/panel/vhost/cert/mail.adminslab.com/privkey.pem</code></div></div>Pure-FTPd uses <br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/etc/ssl/private/pure-ftpd.pem</code></div></div>Confirm your own hostname, certificate paths and service name first. Do not copy another site's private key or publish the key in a post. Keep the FTP bundle root-owned and readable only by root. Retain a private rollback copy and confirm provider-console access before changing the service.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Install the helper after reviewing it</span><br />
Save the following as <span style="font-weight: bold;" class="mycode_b">/usr/local/sbin/af-sync-ftps-certificate.py</span> using your authorized root session. The code below is the lab version. Adapt the hostname, source folder and private backup folder to your server before using it. It expects Python 3, OpenSSL, ss and systemctl, and the existing pure-ftpd.service.<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>#!/usr/bin/python3
"""Deploy an already-renewed aaPanel certificate to Pure-FTPd without exposing its key."""
import argparse,fcntl,hashlib,os,ssl,subprocess,tempfile
from pathlib import Path
parser=argparse.ArgumentParser();parser.add_argument('--dry-run',action='store_true');args=parser.parse_args()
if os.geteuid()!=0: raise SystemExit('Root required')
lock=open('/run/af-ftps-certificate-sync.lock','w');fcntl.flock(lock,fcntl.LOCK_EX|fcntl.LOCK_NB)
source=Path('/www/server/panel/vhost/cert/mail.adminslab.com');target=Path('/etc/ssl/private/pure-ftpd.pem')
cert=source/'fullchain.pem';key=source/'privkey.pem'
for p in [cert,key,target]:
 if not p.is_file() or p.is_symlink():raise SystemExit('Expected regular certificate file missing')
subprocess.run(['openssl','x509','-in',str(cert),'-noout','-checkend','604800'],check=True,stdout=subprocess.DEVNULL)
subprocess.run(['openssl','verify','-CApath','/etc/ssl/certs','-verify_hostname','mail.adminslab.com','-untrusted',str(cert),str(cert)],check=True,stdout=subprocess.DEVNULL)
bundle=cert.read_bytes().rstrip()+bytes([10])+key.read_bytes().rstrip()+bytes([10])
fd,name=tempfile.mkstemp(prefix='.af-ftps-',dir=str(target.parent));tmp=Path(name)
try:
 os.fchmod(fd,0o600)
 with os.fdopen(fd,'wb') as out:out.write(bundle);out.flush();os.fsync(out.fileno())
 context=ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER);context.load_cert_chain(str(tmp))
 old=target.read_bytes()
 if old==bundle:print('FTPS certificate already synchronized; no restart');raise SystemExit(0)
 if args.dry_run:print('DRY RUN PASS: chain, hostname, expiry and matching key validated; update required');raise SystemExit(0)
 sessions=subprocess.check_output(['ss','-Hnt','state','established','sport','=',':21'],text=True)
 if sessions.strip():raise SystemExit('Active FTP control session: deferred until next run')
 backup=Path('/root/af-hosting-batch-20261012/ftps-renewal-20261013');backup.mkdir(mode=0o700,parents=True,exist_ok=True)
 previous=backup/'previous-bundle.pem';previous.write_bytes(old);previous.chmod(0o600)
 os.replace(tmp,target);os.chmod(target,0o600)
 try:
  subprocess.run(['systemctl','restart','pure-ftpd.service'],check=True)
 except Exception:
  target.write_bytes(old);target.chmod(0o600);subprocess.run(['systemctl','restart','pure-ftpd.service'],check=False);raise
 print('FTPS certificate deployed; Pure-FTPd restarted')
finally:
 if tmp.exists():tmp.unlink()</code></div></div>Then set its ownership/permissions and run a dry check:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>chown root:root /usr/local/sbin/af-sync-ftps-certificate.py
chmod 700 /usr/local/sbin/af-sync-ftps-certificate.py
/usr/local/sbin/af-sync-ftps-certificate.py --dry-run</code></div></div>The helper checks the certificate chain and hostname, a seven-day remaining-validity margin, and that the key matches the certificate. If the existing bundle already matches, it exits without restarting FTP. If a control connection is active, a live deployment is deferred. A failure message needs investigation; do not bypass the validation just to make the job complete.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Deploy once and verify trusted FTPS</span><br />
Run the helper without --dry-run. When the source differs, it preserves the previous bundle privately, replaces the file with mode 600 and restarts Pure-FTPd. It attempts to restore the old bundle if the restart fails.<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/usr/local/sbin/af-sync-ftps-certificate.py</code></div></div>Reconnect using the certificate's hostname and explicit FTPS. Confirm certificate validation succeeds. Do not use an IP address as the hostname when the certificate covers a DNS name. Check an encrypted upload/download after a real renewal, not just the certificate's displayed expiration date.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=138" target="_blank" title="">ftps-sync-branded-20261013.jpg</a> (Size: 58.93 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Actual lab deployment: updated bundle, trusted TLS 1.3, then an unchanged second run with no restart.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Add the scheduled check</span><br />
Our lab uses a root-owned /etc/cron.d/af-ftps-certificate-sync file with:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SHELL=/bin/sh
PATH=/usr/sbin:/usr/bin:/sbin:/bin
17 * * * * root /usr/local/sbin/af-sync-ftps-certificate.py &gt;&gt; /var/log/af-ftps-certificate-sync.log 2&gt;&amp;1</code></div></div>This runs at minute 17 of each hour in the server's configured timezone. Use only one copy of the schedule; do not also create an identical panel task. Set the schedule file to root ownership and mode 644, and pre-create the log root-owned with mode 600. Check that the cron daemon is running. If you prefer aaPanel Cron, create the equivalent root Shell Script task and use the helper command, with private logging.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Monitor the complete renewal path</span><br />
Read the private log for validation errors, deferred sessions or a failed restart. Inspect source certificate expiration and the actual certificate presented by FTPS. Persistent FTP sessions can delay deployment; plan a maintenance window if that continues. The old backup bundle includes a private key and must remain private. Arrange suitable log retention and an alert route outside the server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Troubleshooting</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Source missing:</span> confirm the actual aaPanel certificate folder and that renewal produced files.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Chain/hostname check fails:</span> confirm the certificate covers the FTPS hostname and includes the necessary intermediate certificates.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Key mismatch:</span> use the key from the same certificate issuance; never guess or combine unrelated files.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Expiry margin fails:</span> repair the original renewal process before attempting deployment.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Active session deferred:</span> wait for transfers to finish; the next scheduled run can retry.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">FTP restart fails:</span> inspect the service configuration and restore the private previous bundle if required.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Verified scope</span><br />
The lab passed dry validation, live deployment, trusted FTPS TLS 1.3, an unchanged no-restart run, and cron-service/schedule checks. A future certificate issuance and a future automatic renewal have not yet occurred, so this is not a claim that the next renewal has already succeeded. The existing aaPanel certificate-renewal job was preserved.<br />
<br />
<a href="https://adminsforum.com/Thread-guide-enable-ftps-encryption-and-ssl-for-pure-ftpd-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Start with the FTPS setup guide</a>. Original helper and lab evidence: © AdminsForum.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Connect FileZilla to aaPanel with Secure FTPS]]></title>
			<link>https://adminsforum.com/Thread-guide-connect-filezilla-to-aapanel-with-secure-ftps</link>
			<pubDate>Tue, 13 Oct 2026 10:38:48 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-connect-filezilla-to-aapanel-with-secure-ftps</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
Use FileZilla Site Manager with protocol FTP, port 21 and “Require explicit FTP over TLS”. Enter the hostname covered by your server certificate and a separate restricted FTP account. SFTP is an SSH connection and uses different server credentials; it is not a Pure-FTPd account.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Before connecting</span><br />
Complete <a href="https://adminsforum.com/Thread-guide-enable-ftps-encryption-and-ssl-for-pure-ftpd-in-aapanel" target="_blank" rel="noopener" class="mycode_url">the FTPS server setup</a> first. Confirm the service is running, the certificate is valid and your FTP account points to the correct directory. Install FileZilla Client from <a href="https://filezilla-project.org/" target="_blank" rel="noopener" class="mycode_url">its official website</a>. You need the Client application, not FileZilla Server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Create a saved site</span><br />
Open File → Site Manager, or press Ctrl+S. Choose New Site and give it a recognizable label such as “AdminsForum lab — FTPS”. Select the General tab and enter your own server details. The following reference shows our lab settings, not a screenshot of a running FileZilla session.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=116" target="_blank" title="">filezilla-ftps-settings-20261013.jpg</a> (Size: 116.26 KB / Downloads: 10)
<!-- end: postbit_attachments_attachment --><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Host:</span> mail.adminslab.com in our lab. Enter your certificate hostname without https:// or a folder path.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Port:</span> 21 for this explicit FTPS setup.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Protocol:</span> FTP — File Transfer Protocol.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Encryption:</span> Require explicit FTP over TLS. Avoid an option that falls back to unencrypted FTP.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Logon type:</span> Ask for password, so the saved site does not need to store it permanently.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">User:</span> your separate restricted FTP username; af_ftp_lab in our test.<br />
</li>
</ul>
In Transfer Settings, use Passive mode. Save the site and select Connect. Enter your own existing FTP password when prompted; do not put it in guide screenshots.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check the certificate</span><br />
The server identity must match the hostname you entered. If the certificate is expired, belongs to a different name or has an incomplete chain, stop and correct the server configuration. Do not routinely accept an unrelated certificate just to make the connection work.<br />
Our backend test accepted the normal certificate chain and mail.adminslab.com hostname, negotiated TLS 1.3 and used encrypted data connections. That server test used a Python FTPS client; this article does not claim that FileZilla desktop screenshots or transfers were captured.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Understand the two file panes</span><br />
The local pane displays files on your computer. The remote pane displays files the FTP account is allowed to access on the server. A restricted account's remote / means its assigned folder, not the Linux server's real root directory.<br />
Our account is restricted to /www/wwwroot/adminslab.com/ftp-lab. Do not try to enter another website path as a workaround. If you need another folder, have the administrator assign the correct scope rather than using a root login.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Upload a harmless test file</span><br />
Create a small text file on your computer named ftp-check.txt with a unique sentence. In the remote pane, confirm you are in the intended test folder. Drag the file from the local pane into that folder, or use the file's Upload action.<br />
Check the transfer queue. The transfer should complete and appear in the successful list. Refresh the remote directory and confirm the filename and size. Do not test by overwriting a live index.php, wp-config.php or another production file.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Download and compare</span><br />
Download the uploaded file into a different local folder. Open it and compare the sentence with the original, or compare its SHA-256 hash. A successful login alone does not prove that the data connection works; an upload and matching download provide a stronger check.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=117" target="_blank" title="">batch11-ftps-proof-branded.jpg</a> (Size: 81.76 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
The lab's certificate-verifying FTPS test confirmed matching uploaded/downloaded contents and hash. It also refused access outside the assigned root.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Disconnect and keep credentials private</span><br />
Disconnect when finished. Keep the test file only if it is useful for the lab; do not remove other server files. Never share an exported Site Manager configuration without checking whether it contains saved passwords or private server information.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Common connection problems</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Connection refused or timeout before login:</span> check that Pure-FTPd is running, DNS points to the server and the configured control port is reachable.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Login rejected:</span> verify the username, password and enabled account. An FTP account is not automatically an SSH user.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Login works but directory listing hangs:</span> check Passive mode, the server's actual passive port range and both server/provider firewalls. Our lab range is 39000–40000; use your configured range.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Plaintext connection rejected:</span> expected with TLS 3. Select explicit FTPS and require encryption.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Certificate name mismatch:</span> use the certificate hostname, not an unrelated domain or raw IP.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Permission denied on upload:</span> confirm the assigned directory and filesystem ownership. Do not solve it by applying world-writable permissions across the server.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">FTP, FTPS or SFTP?</span><br />
FTP without TLS exposes login and file traffic. FTPS adds TLS to FTP and uses separate control/data connections. SFTP transfers files through SSH, normally over the server's SSH port. Select the protocol that matches the service you configured; changing a dropdown does not create that service or account.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference:</span> <a href="https://wiki.filezilla-project.org/Site_Manager" target="_blank" rel="noopener" class="mycode_url">FileZilla Site Manager documentation</a>. © AdminsForum.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
Use FileZilla Site Manager with protocol FTP, port 21 and “Require explicit FTP over TLS”. Enter the hostname covered by your server certificate and a separate restricted FTP account. SFTP is an SSH connection and uses different server credentials; it is not a Pure-FTPd account.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Before connecting</span><br />
Complete <a href="https://adminsforum.com/Thread-guide-enable-ftps-encryption-and-ssl-for-pure-ftpd-in-aapanel" target="_blank" rel="noopener" class="mycode_url">the FTPS server setup</a> first. Confirm the service is running, the certificate is valid and your FTP account points to the correct directory. Install FileZilla Client from <a href="https://filezilla-project.org/" target="_blank" rel="noopener" class="mycode_url">its official website</a>. You need the Client application, not FileZilla Server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Create a saved site</span><br />
Open File → Site Manager, or press Ctrl+S. Choose New Site and give it a recognizable label such as “AdminsForum lab — FTPS”. Select the General tab and enter your own server details. The following reference shows our lab settings, not a screenshot of a running FileZilla session.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=116" target="_blank" title="">filezilla-ftps-settings-20261013.jpg</a> (Size: 116.26 KB / Downloads: 10)
<!-- end: postbit_attachments_attachment --><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Host:</span> mail.adminslab.com in our lab. Enter your certificate hostname without https:// or a folder path.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Port:</span> 21 for this explicit FTPS setup.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Protocol:</span> FTP — File Transfer Protocol.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Encryption:</span> Require explicit FTP over TLS. Avoid an option that falls back to unencrypted FTP.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Logon type:</span> Ask for password, so the saved site does not need to store it permanently.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">User:</span> your separate restricted FTP username; af_ftp_lab in our test.<br />
</li>
</ul>
In Transfer Settings, use Passive mode. Save the site and select Connect. Enter your own existing FTP password when prompted; do not put it in guide screenshots.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check the certificate</span><br />
The server identity must match the hostname you entered. If the certificate is expired, belongs to a different name or has an incomplete chain, stop and correct the server configuration. Do not routinely accept an unrelated certificate just to make the connection work.<br />
Our backend test accepted the normal certificate chain and mail.adminslab.com hostname, negotiated TLS 1.3 and used encrypted data connections. That server test used a Python FTPS client; this article does not claim that FileZilla desktop screenshots or transfers were captured.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Understand the two file panes</span><br />
The local pane displays files on your computer. The remote pane displays files the FTP account is allowed to access on the server. A restricted account's remote / means its assigned folder, not the Linux server's real root directory.<br />
Our account is restricted to /www/wwwroot/adminslab.com/ftp-lab. Do not try to enter another website path as a workaround. If you need another folder, have the administrator assign the correct scope rather than using a root login.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Upload a harmless test file</span><br />
Create a small text file on your computer named ftp-check.txt with a unique sentence. In the remote pane, confirm you are in the intended test folder. Drag the file from the local pane into that folder, or use the file's Upload action.<br />
Check the transfer queue. The transfer should complete and appear in the successful list. Refresh the remote directory and confirm the filename and size. Do not test by overwriting a live index.php, wp-config.php or another production file.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Download and compare</span><br />
Download the uploaded file into a different local folder. Open it and compare the sentence with the original, or compare its SHA-256 hash. A successful login alone does not prove that the data connection works; an upload and matching download provide a stronger check.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=117" target="_blank" title="">batch11-ftps-proof-branded.jpg</a> (Size: 81.76 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
The lab's certificate-verifying FTPS test confirmed matching uploaded/downloaded contents and hash. It also refused access outside the assigned root.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Disconnect and keep credentials private</span><br />
Disconnect when finished. Keep the test file only if it is useful for the lab; do not remove other server files. Never share an exported Site Manager configuration without checking whether it contains saved passwords or private server information.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Common connection problems</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Connection refused or timeout before login:</span> check that Pure-FTPd is running, DNS points to the server and the configured control port is reachable.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Login rejected:</span> verify the username, password and enabled account. An FTP account is not automatically an SSH user.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Login works but directory listing hangs:</span> check Passive mode, the server's actual passive port range and both server/provider firewalls. Our lab range is 39000–40000; use your configured range.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Plaintext connection rejected:</span> expected with TLS 3. Select explicit FTPS and require encryption.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Certificate name mismatch:</span> use the certificate hostname, not an unrelated domain or raw IP.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Permission denied on upload:</span> confirm the assigned directory and filesystem ownership. Do not solve it by applying world-writable permissions across the server.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">FTP, FTPS or SFTP?</span><br />
FTP without TLS exposes login and file traffic. FTPS adds TLS to FTP and uses separate control/data connections. SFTP transfers files through SSH, normally over the server's SSH port. Select the protocol that matches the service you configured; changing a dropdown does not create that service or account.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference:</span> <a href="https://wiki.filezilla-project.org/Site_Manager" target="_blank" rel="noopener" class="mycode_url">FileZilla Site Manager documentation</a>. © AdminsForum.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Enable FTPS Encryption and SSL for Pure-FTPd in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-enable-ftps-encryption-and-ssl-for-pure-ftpd-in-aapanel</link>
			<pubDate>Tue, 13 Oct 2026 10:35:20 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-enable-ftps-encryption-and-ssl-for-pure-ftpd-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">FTPS protects FTP logins and file transfers with TLS.</span> This guide uses Pure-FTPd on aaPanel with explicit FTPS on port 21. SFTP is a different protocol that uses SSH; selecting SFTP in a client will not connect to Pure-FTPd.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Before you start</span><ul class="mycode_list"><li>Pure-FTPd is installed and running.<br />
</li>
<li>You have a separate FTP user restricted to the intended website folder.<br />
</li>
<li>A DNS-only hostname points to the server. Our lab uses mail.adminslab.com because its existing trusted certificate covers that name.<br />
</li>
<li>You have the matching private key and full certificate chain, and a backup of the current FTP configuration and certificate.<br />
</li>
</ul>
Do not use a certificate for a different hostname. Ordinary Cloudflare proxying does not proxy FTP, so keep the FTP hostname DNS only.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Check the existing service</span><br />
In aaPanel, open App Store → Installed → Pure-FTPd → Setting. Confirm that the service is running. Keep your working panel and SSH sessions open while making configuration changes.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Back up the configuration</span><br />
Our lab configuration is /www/server/pure-ftpd/etc/pure-ftpd.conf. Before editing, save a private copy of this file and the current /etc/ssl/private/pure-ftpd.pem certificate bundle. Paths can differ between installations; verify the file your service actually loads.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Prepare a trusted certificate bundle</span><br />
Pure-FTPd can load a PEM bundle containing the private key and full certificate chain. In our lab, the existing Let's Encrypt certificate and matching key were verified before creating /etc/ssl/private/pure-ftpd.pem. The bundle is owned by root with permissions 0600. Never post or upload its private key to a forum.<br />
The name entered in your FTP client must match the certificate. Our certificate is valid for mail.adminslab.com, not the server IP.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=113" target="_blank" title="">batch11-ftps-cert-branded.jpg</a> (Size: 56.8 KB / Downloads: 11)
<!-- end: postbit_attachments_attachment --><br />
The lab certificate bundle and strict TLS configuration were verified before restarting the service.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Require encryption for both connections</span><br />
Set the following directives in the active Pure-FTPd configuration:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>TLS 3
CertFile /etc/ssl/private/pure-ftpd.pem
ChrootEveryone yes
NoAnonymous yes
PassivePortRange 39000 40000</code></div></div>TLS 3 requires TLS for both the login/control connection and the file-transfer/data connection. TLS 1 permits plaintext FTP, and TLS 2 only requires encryption on the control connection. Save the configuration and restart Pure-FTPd. If the service fails, check its log and restore the backed-up configuration instead of repeatedly changing unrelated settings.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Check passive ports</span><br />
Explicit FTPS uses port 21 for the control connection. Passive transfers also need the configured data-port range permitted by the server and provider firewalls. The lab already allowed TCP 39000–40000; this test did not open additional public ports. Use your actual configured range. Do not open Redis, database or panel backend ports to solve an FTP error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Connect securely</span><br />
In your FTP client select FTP, explicit FTP over TLS, port 21, the certificate hostname and the restricted account. In FileZilla, choose “Require explicit FTP over TLS”. Keep certificate verification enabled. A name mismatch or expired certificate needs correction on the server or hostname; do not turn validation off.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Verify the result</span><br />
Our lab tests confirmed:<ul class="mycode_list"><li>The certificate chain and hostname were accepted by a client using its normal trusted CA store.<br />
</li>
<li>The control connection negotiated TLS 1.3.<br />
</li>
<li>A protected data connection uploaded and downloaded a test file with matching contents and SHA-256 hash.<br />
</li>
<li>The restricted account could not access another website folder.<br />
</li>
<li>A plaintext connection was rejected with “Please reconnect using TLS security mechanisms.”<br />
</li>
</ul>
The client test used Python's FTPS client. It proves the server transfer path; it does not claim a FileZilla desktop session was tested.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=114" target="_blank" title="">batch11-ftps-transport-branded.jpg</a> (Size: 75.3 KB / Downloads: 11)
<!-- end: postbit_attachments_attachment --><br />
Plaintext FTP was refused; the certificate-verified connection negotiated TLS 1.3.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=115" target="_blank" title="">batch11-ftps-proof-branded.jpg</a> (Size: 81.76 KB / Downloads: 11)
<!-- end: postbit_attachments_attachment --><br />
Protected upload/download and directory restriction passed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><br />
<span style="font-weight: bold;" class="mycode_b">Login works but listing or transfers hang:</span> check passive ports, the provider firewall and the advertised server address.<br />
<span style="font-weight: bold;" class="mycode_b">Certificate error:</span> verify the client hostname, certificate expiry, complete chain and matching private key.<br />
<span style="font-weight: bold;" class="mycode_b">Plain FTP no longer works:</span> this is expected with TLS 3; configure explicit FTPS in the client.<br />
<span style="font-weight: bold;" class="mycode_b">Cannot leave the assigned folder:</span> this is expected for the restricted account. Its FTP root is not the server filesystem root.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Certificate renewal</span><br />
Copying a certificate into the FTP bundle does not automatically update that bundle after renewal. Renew the certificate, securely rebuild the bundle, restart Pure-FTPd and repeat certificate and transfer checks. Our lab certificate expires on 9 January 2027; no automatic FTP redeployment hook was added in this test.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-install-pure-ftpd-in-aapanel-and-check-the-ftp-service" target="_blank" rel="noopener" class="mycode_url">Install Pure-FTPd and check its service</a><br />
<a href="https://adminsforum.com/Thread-guide-create-a-restricted-ftp-account-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Create a restricted FTP account</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">References</span><br />
<a href="https://www.aapanel.com/docs/Function/Ftp.html" target="_blank" rel="noopener" class="mycode_url">aaPanel FTP documentation</a><br />
<a href="https://github.com/jedisct1/pure-ftpd/blob/master/README.TLS" target="_blank" rel="noopener" class="mycode_url">Pure-FTPd TLS documentation</a><br />
<a href="https://developers.cloudflare.com/fundamentals/reference/network-ports/" target="_blank" rel="noopener" class="mycode_url">Cloudflare supported proxy ports</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Certificate renewal follow-up</span><br />
The lab now uses a validated hourly synchronization helper to deploy the renewed aaPanel certificate into the separate Pure-FTPd bundle. Dry validation, deployment, trusted TLS and an unchanged second run passed. Future renewal has not yet occurred. <a href="https://adminsforum.com/Thread-guide-automatically-update-the-pure-ftpd-ftps-certificate-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Follow the complete automatic certificate-update guide</a>.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">FTPS protects FTP logins and file transfers with TLS.</span> This guide uses Pure-FTPd on aaPanel with explicit FTPS on port 21. SFTP is a different protocol that uses SSH; selecting SFTP in a client will not connect to Pure-FTPd.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Before you start</span><ul class="mycode_list"><li>Pure-FTPd is installed and running.<br />
</li>
<li>You have a separate FTP user restricted to the intended website folder.<br />
</li>
<li>A DNS-only hostname points to the server. Our lab uses mail.adminslab.com because its existing trusted certificate covers that name.<br />
</li>
<li>You have the matching private key and full certificate chain, and a backup of the current FTP configuration and certificate.<br />
</li>
</ul>
Do not use a certificate for a different hostname. Ordinary Cloudflare proxying does not proxy FTP, so keep the FTP hostname DNS only.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Check the existing service</span><br />
In aaPanel, open App Store → Installed → Pure-FTPd → Setting. Confirm that the service is running. Keep your working panel and SSH sessions open while making configuration changes.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Back up the configuration</span><br />
Our lab configuration is /www/server/pure-ftpd/etc/pure-ftpd.conf. Before editing, save a private copy of this file and the current /etc/ssl/private/pure-ftpd.pem certificate bundle. Paths can differ between installations; verify the file your service actually loads.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Prepare a trusted certificate bundle</span><br />
Pure-FTPd can load a PEM bundle containing the private key and full certificate chain. In our lab, the existing Let's Encrypt certificate and matching key were verified before creating /etc/ssl/private/pure-ftpd.pem. The bundle is owned by root with permissions 0600. Never post or upload its private key to a forum.<br />
The name entered in your FTP client must match the certificate. Our certificate is valid for mail.adminslab.com, not the server IP.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=113" target="_blank" title="">batch11-ftps-cert-branded.jpg</a> (Size: 56.8 KB / Downloads: 11)
<!-- end: postbit_attachments_attachment --><br />
The lab certificate bundle and strict TLS configuration were verified before restarting the service.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Require encryption for both connections</span><br />
Set the following directives in the active Pure-FTPd configuration:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>TLS 3
CertFile /etc/ssl/private/pure-ftpd.pem
ChrootEveryone yes
NoAnonymous yes
PassivePortRange 39000 40000</code></div></div>TLS 3 requires TLS for both the login/control connection and the file-transfer/data connection. TLS 1 permits plaintext FTP, and TLS 2 only requires encryption on the control connection. Save the configuration and restart Pure-FTPd. If the service fails, check its log and restore the backed-up configuration instead of repeatedly changing unrelated settings.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Check passive ports</span><br />
Explicit FTPS uses port 21 for the control connection. Passive transfers also need the configured data-port range permitted by the server and provider firewalls. The lab already allowed TCP 39000–40000; this test did not open additional public ports. Use your actual configured range. Do not open Redis, database or panel backend ports to solve an FTP error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Connect securely</span><br />
In your FTP client select FTP, explicit FTP over TLS, port 21, the certificate hostname and the restricted account. In FileZilla, choose “Require explicit FTP over TLS”. Keep certificate verification enabled. A name mismatch or expired certificate needs correction on the server or hostname; do not turn validation off.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Verify the result</span><br />
Our lab tests confirmed:<ul class="mycode_list"><li>The certificate chain and hostname were accepted by a client using its normal trusted CA store.<br />
</li>
<li>The control connection negotiated TLS 1.3.<br />
</li>
<li>A protected data connection uploaded and downloaded a test file with matching contents and SHA-256 hash.<br />
</li>
<li>The restricted account could not access another website folder.<br />
</li>
<li>A plaintext connection was rejected with “Please reconnect using TLS security mechanisms.”<br />
</li>
</ul>
The client test used Python's FTPS client. It proves the server transfer path; it does not claim a FileZilla desktop session was tested.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=114" target="_blank" title="">batch11-ftps-transport-branded.jpg</a> (Size: 75.3 KB / Downloads: 11)
<!-- end: postbit_attachments_attachment --><br />
Plaintext FTP was refused; the certificate-verified connection negotiated TLS 1.3.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=115" target="_blank" title="">batch11-ftps-proof-branded.jpg</a> (Size: 81.76 KB / Downloads: 11)
<!-- end: postbit_attachments_attachment --><br />
Protected upload/download and directory restriction passed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><br />
<span style="font-weight: bold;" class="mycode_b">Login works but listing or transfers hang:</span> check passive ports, the provider firewall and the advertised server address.<br />
<span style="font-weight: bold;" class="mycode_b">Certificate error:</span> verify the client hostname, certificate expiry, complete chain and matching private key.<br />
<span style="font-weight: bold;" class="mycode_b">Plain FTP no longer works:</span> this is expected with TLS 3; configure explicit FTPS in the client.<br />
<span style="font-weight: bold;" class="mycode_b">Cannot leave the assigned folder:</span> this is expected for the restricted account. Its FTP root is not the server filesystem root.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Certificate renewal</span><br />
Copying a certificate into the FTP bundle does not automatically update that bundle after renewal. Renew the certificate, securely rebuild the bundle, restart Pure-FTPd and repeat certificate and transfer checks. Our lab certificate expires on 9 January 2027; no automatic FTP redeployment hook was added in this test.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-install-pure-ftpd-in-aapanel-and-check-the-ftp-service" target="_blank" rel="noopener" class="mycode_url">Install Pure-FTPd and check its service</a><br />
<a href="https://adminsforum.com/Thread-guide-create-a-restricted-ftp-account-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Create a restricted FTP account</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">References</span><br />
<a href="https://www.aapanel.com/docs/Function/Ftp.html" target="_blank" rel="noopener" class="mycode_url">aaPanel FTP documentation</a><br />
<a href="https://github.com/jedisct1/pure-ftpd/blob/master/README.TLS" target="_blank" rel="noopener" class="mycode_url">Pure-FTPd TLS documentation</a><br />
<a href="https://developers.cloudflare.com/fundamentals/reference/network-ports/" target="_blank" rel="noopener" class="mycode_url">Cloudflare supported proxy ports</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Certificate renewal follow-up</span><br />
The lab now uses a validated hourly synchronization helper to deploy the renewed aaPanel certificate into the separate Pure-FTPd bundle. Dry validation, deployment, trusted TLS and an unchanged second run passed. Future renewal has not yet occurred. <a href="https://adminsforum.com/Thread-guide-automatically-update-the-pure-ftpd-ftps-certificate-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Follow the complete automatic certificate-update guide</a>.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Create a Restricted FTP Account in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-create-a-restricted-ftp-account-in-aapanel</link>
			<pubDate>Tue, 13 Oct 2026 10:01:02 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-create-a-restricted-ftp-account-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
In aaPanel's FTP module, choose Add FTP, enter a separate username and unique password, and assign only the directory that user needs. Confirm the saved account/root, then test it over FTPS. Do not give a transfer user the server's root login or assign /www/wwwroot when they only need one folder.<br />
<br />
We created af_ftp_lab on our aaPanel 8.0.6 Ubuntu lab and restricted it to /www/wwwroot/adminslab.com/ftp-lab. A verified encrypted upload/download test passed, and an attempt to access a different website path through FTP was refused.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Prepare the server and destination folder</span><br />
Confirm Pure-FTPd is installed and started. Follow <a href="https://adminsforum.com/Thread-guide-install-pure-ftpd-in-aapanel-and-check-the-ftp-service" target="_blank" rel="noopener" class="mycode_url">the installation/service guide</a> first if necessary.<br />
<br />
Decide exactly which directory the user needs. A website administrator may need that website's root; a narrow transfer task may need only a subfolder. Our test needed only a dedicated lab folder, so we did not grant access to the parent website directory or other sites.<br />
<br />
Check the intended folder and its contents before creating the account. Avoid copying a path from an unrelated website. If you use a new folder, confirm the saved directory exists after account creation and has appropriate ownership for the intended workflow.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Open Add FTP and enter the fields</span><br />
Open FTP → Add FTP. The dialog contains Username, Password and Document Root.<ul class="mycode_list"><li>Username: choose a separate identifiable name. Our actual account was af_ftp_lab.<br />
</li>
<li>Password: use a long unique value; keep it private. The panel can generate a value. Do not reuse the panel/root password or publish it in a screenshot.<br />
</li>
<li>Document Root: assign the exact authorized directory. Our value was /www/wwwroot/adminslab.com/ftp-lab.<br />
</li>
</ul>
<br />
Review all three fields, then Confirm. Wait until the account appears in the table. If the dialog reports a validation error, correct the relevant field instead of repeatedly submitting it.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Verify the saved account</span><br />
Our FTP table showed the account, a masked password, Running status and the exact restricted root. The screenshot includes the Add FTP action and the saved result; the password remains hidden.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=111" target="_blank" title="">batch11-ftp-account-branded.jpg</a> (Size: 121.69 KB / Downloads: 11)
<!-- end: postbit_attachments_attachment --><br />
<br />
Running here refers to the account's enabled state. Also check the Pure-FTPd service itself. A valid saved user cannot log in if the server is stopped.<br />
<br />
Review the Quota field before assuming a storage cap is enforced. Our test displayed Not set. This walkthrough does not claim that an unspecified quota limits disk consumption; check your filesystem/panel support before using quotas as a control.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Connect with encrypted FTP</span><br />
Use a certificate-matching hostname and require explicit FTP over TLS. A client profile for our test used:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Protocol: FTP
Encryption: require explicit FTP over TLS
Host: mail.adminslab.com
Port: 21
User: af_ftp_lab
Transfer mode: passive</code></div></div><br />
The password is deliberately omitted. The hostname must match the server's FTPS certificate. The panel's displayed ftp:// IP address alone does not establish a secure client profile.<br />
<br />
FTPS and SFTP are different protocols. This FTP account is not automatically an SSH/SFTP account. If your client is set to SFTP, it will contact the SSH service and use that service's authentication instead.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Test both directions and the root restriction</span><br />
After login, a client may show / as its remote directory. That is the FTP account's logical root, not evidence that it can see the entire server filesystem.<br />
<br />
Upload a small original file, refresh the remote listing, then download it again and compare its contents or checksum. We transferred adminsforum-ftps-proof.txt through protected data connections and verified identical bytes and SHA-256 after download.<br />
<br />
Next, verify the account stays inside its assigned root. Our client was refused when it requested another website's absolute filesystem path. That checks FTP directory isolation; it is separate from application or operating-system isolation.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=112" target="_blank" title="">batch11-ftps-proof-branded.jpg</a> (Size: 81.76 KB / Downloads: 11)
<!-- end: postbit_attachments_attachment --><br />
<br />
The certificate chain and hostname were verified, TLS 1.3 was negotiated, and the data connection was protected. We did not disable certificate verification to make the test pass.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Manage the account afterward</span><br />
The saved row exposes Set Path, Password and Log actions. Review a path change carefully before applying it; broadening the root broadens the files the user can reach. If your panel offers migration while changing a root, understand its copy behavior before using it.<br />
<br />
Change passwords privately, update the intended client profile and retest. Inspect the account's log when troubleshooting. Disable an account when it no longer needs access; deleting an account is a separate action and should not be treated as a routine cure for an authentication error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><ul class="mycode_list"><li>Authentication fails: check enabled status and the exact username/password, without showing the password in logs or public support posts.<br />
</li>
<li>Login works but a listing stalls: check passive mode, its configured port range, and both server/provider firewalls.<br />
</li>
<li>File upload is denied: inspect the assigned root, ownership and available space rather than using world-writable permissions everywhere.<br />
</li>
<li>Certificate warning: correct the hostname/certificate/chain; do not send credentials until verification succeeds.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Verified result</span><br />
The saved root matched the intended lab folder, an encrypted round-trip transfer passed and another website path was refused. Our test used a certificate-verifying FTPS client in the lab; the result is not based only on the account's Running label.<br />
<br />
Reference: <a href="https://www.aapanel.com/docs/Function/Ftp.html" target="_blank" rel="noopener" class="mycode_url">aaPanel FTP account management</a>. © AdminsForum.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
In aaPanel's FTP module, choose Add FTP, enter a separate username and unique password, and assign only the directory that user needs. Confirm the saved account/root, then test it over FTPS. Do not give a transfer user the server's root login or assign /www/wwwroot when they only need one folder.<br />
<br />
We created af_ftp_lab on our aaPanel 8.0.6 Ubuntu lab and restricted it to /www/wwwroot/adminslab.com/ftp-lab. A verified encrypted upload/download test passed, and an attempt to access a different website path through FTP was refused.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Prepare the server and destination folder</span><br />
Confirm Pure-FTPd is installed and started. Follow <a href="https://adminsforum.com/Thread-guide-install-pure-ftpd-in-aapanel-and-check-the-ftp-service" target="_blank" rel="noopener" class="mycode_url">the installation/service guide</a> first if necessary.<br />
<br />
Decide exactly which directory the user needs. A website administrator may need that website's root; a narrow transfer task may need only a subfolder. Our test needed only a dedicated lab folder, so we did not grant access to the parent website directory or other sites.<br />
<br />
Check the intended folder and its contents before creating the account. Avoid copying a path from an unrelated website. If you use a new folder, confirm the saved directory exists after account creation and has appropriate ownership for the intended workflow.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Open Add FTP and enter the fields</span><br />
Open FTP → Add FTP. The dialog contains Username, Password and Document Root.<ul class="mycode_list"><li>Username: choose a separate identifiable name. Our actual account was af_ftp_lab.<br />
</li>
<li>Password: use a long unique value; keep it private. The panel can generate a value. Do not reuse the panel/root password or publish it in a screenshot.<br />
</li>
<li>Document Root: assign the exact authorized directory. Our value was /www/wwwroot/adminslab.com/ftp-lab.<br />
</li>
</ul>
<br />
Review all three fields, then Confirm. Wait until the account appears in the table. If the dialog reports a validation error, correct the relevant field instead of repeatedly submitting it.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Verify the saved account</span><br />
Our FTP table showed the account, a masked password, Running status and the exact restricted root. The screenshot includes the Add FTP action and the saved result; the password remains hidden.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=111" target="_blank" title="">batch11-ftp-account-branded.jpg</a> (Size: 121.69 KB / Downloads: 11)
<!-- end: postbit_attachments_attachment --><br />
<br />
Running here refers to the account's enabled state. Also check the Pure-FTPd service itself. A valid saved user cannot log in if the server is stopped.<br />
<br />
Review the Quota field before assuming a storage cap is enforced. Our test displayed Not set. This walkthrough does not claim that an unspecified quota limits disk consumption; check your filesystem/panel support before using quotas as a control.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Connect with encrypted FTP</span><br />
Use a certificate-matching hostname and require explicit FTP over TLS. A client profile for our test used:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Protocol: FTP
Encryption: require explicit FTP over TLS
Host: mail.adminslab.com
Port: 21
User: af_ftp_lab
Transfer mode: passive</code></div></div><br />
The password is deliberately omitted. The hostname must match the server's FTPS certificate. The panel's displayed ftp:// IP address alone does not establish a secure client profile.<br />
<br />
FTPS and SFTP are different protocols. This FTP account is not automatically an SSH/SFTP account. If your client is set to SFTP, it will contact the SSH service and use that service's authentication instead.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Test both directions and the root restriction</span><br />
After login, a client may show / as its remote directory. That is the FTP account's logical root, not evidence that it can see the entire server filesystem.<br />
<br />
Upload a small original file, refresh the remote listing, then download it again and compare its contents or checksum. We transferred adminsforum-ftps-proof.txt through protected data connections and verified identical bytes and SHA-256 after download.<br />
<br />
Next, verify the account stays inside its assigned root. Our client was refused when it requested another website's absolute filesystem path. That checks FTP directory isolation; it is separate from application or operating-system isolation.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=112" target="_blank" title="">batch11-ftps-proof-branded.jpg</a> (Size: 81.76 KB / Downloads: 11)
<!-- end: postbit_attachments_attachment --><br />
<br />
The certificate chain and hostname were verified, TLS 1.3 was negotiated, and the data connection was protected. We did not disable certificate verification to make the test pass.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Manage the account afterward</span><br />
The saved row exposes Set Path, Password and Log actions. Review a path change carefully before applying it; broadening the root broadens the files the user can reach. If your panel offers migration while changing a root, understand its copy behavior before using it.<br />
<br />
Change passwords privately, update the intended client profile and retest. Inspect the account's log when troubleshooting. Disable an account when it no longer needs access; deleting an account is a separate action and should not be treated as a routine cure for an authentication error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><ul class="mycode_list"><li>Authentication fails: check enabled status and the exact username/password, without showing the password in logs or public support posts.<br />
</li>
<li>Login works but a listing stalls: check passive mode, its configured port range, and both server/provider firewalls.<br />
</li>
<li>File upload is denied: inspect the assigned root, ownership and available space rather than using world-writable permissions everywhere.<br />
</li>
<li>Certificate warning: correct the hostname/certificate/chain; do not send credentials until verification succeeds.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Verified result</span><br />
The saved root matched the intended lab folder, an encrypted round-trip transfer passed and another website path was refused. Our test used a certificate-verifying FTPS client in the lab; the result is not based only on the account's Running label.<br />
<br />
Reference: <a href="https://www.aapanel.com/docs/Function/Ftp.html" target="_blank" rel="noopener" class="mycode_url">aaPanel FTP account management</a>. © AdminsForum.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Install Pure-FTPd in aaPanel and Check the FTP Service]]></title>
			<link>https://adminsforum.com/Thread-guide-install-pure-ftpd-in-aapanel-and-check-the-ftp-service</link>
			<pubDate>Tue, 13 Oct 2026 09:56:01 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-install-pure-ftpd-in-aapanel-and-check-the-ftp-service</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
Use aaPanel App Store to install Pure-FTPd if it is missing. Then open its Setting → Service page, confirm the service is started and configure a separate restricted account plus FTPS before using it for website transfers. Installing an FTP server does not automatically prove that a client can log in or transfer files securely.<br />
<br />
Our lab ran aaPanel 8.0.6 on Ubuntu 22.04 with Pure-FTPd 1.0.49. This walkthrough verifies the existing installation, native service start and subsequent encrypted connection checks. The download/reinstallation step was not repeated on the already installed service.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Decide whether you need FTP</span><br />
Pure-FTPd supplies FTP and FTPS. FTPS adds TLS encryption to the FTP protocol. SFTP is a different protocol supplied through SSH; installing Pure-FTPd is not required for SFTP.<br />
<br />
Use a dedicated FTP account when you want to limit a transfer user to an assigned directory without giving them the server's root SSH login. FTP credentials that can modify website files are still sensitive: those files can change the site's behavior.<br />
<br />
Keep existing administrator access working while setting up a new transfer method. Record the current service configuration and firewall rules before changing them. We preserved private configuration copies on the disposable lab.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Find Pure-FTPd in the App Store</span><br />
Open App Store → Official App. Search for Pure-FTPd or use the Deployment category. If it is not installed, use the official row's Install action, review the offered version/method and confirm the installation. Wait for the installation task to finish and inspect any error rather than repeatedly clicking Install.<br />
<br />
If Installed already shows Pure-FTPd with Setting and Uninstall, open Setting. Do not uninstall a functioning transfer service merely to follow the fresh-install branch of a tutorial.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=109" target="_blank" title="">batch11-ftp-installed-branded.jpg</a> (Size: 252.74 KB / Downloads: 9)
<!-- end: postbit_attachments_attachment --><br />
<br />
Our installed list showed Pure-FTPd 1.0.49. Versions and available packages depend on the operating system and current aaPanel catalog. Record the installed version rather than treating an example version number as a permanent recommendation.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Check and start the service</span><br />
Open Pure-FTPd → Setting → Service. If it is stopped, click Start, review the service confirmation and Confirm. Wait for completion, then reopen or refresh the manager and verify Current state is Start and the action has changed to Stop.<br />
<br />
The lab's native service view showed that started state. The same menu exposes configuration, user management, port settings and logs.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=110" target="_blank" title="">batch11-ftp-service-branded.jpg</a> (Size: 82.42 KB / Downloads: 9)
<!-- end: postbit_attachments_attachment --><br />
<br />
A started service is only the first check. If Start fails, inspect its error/configuration result and port conflicts. Do not disable the firewall or stop unrelated web/SSH services to get past an FTP error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Understand control and passive data connections</span><br />
The panel displayed a control address on TCP port 21. Our actual Pure-FTPd configuration used passive data ports 39000–40000. FTP uses a control connection for commands and separate data connections for listings and file transfers, so a successful login with a stalled listing often points to the data path.<br />
<br />
Inspect the configured range before writing firewall rules. The system firewall and any provider firewall must allow the required control/data traffic for the intended clients. Our lab already had its FTP rules; no new public ports were opened during this test. Do not copy an arbitrary passive range that differs from the running service.<br />
<br />
For a private workflow, restrict source addresses where practical. Do not expose database, Redis or internal web-server backend ports as part of FTP setup.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Create the account and secure the connection</span><br />
Open the FTP module and use Add FTP. Assign a unique user to the exact required document root, not /www/wwwroot or a server-wide folder. Use a strong unique password and keep it out of screenshots and tutorial text.<br />
<br />
We created af_ftp_lab only under /www/wwwroot/adminslab.com/ftp-lab. The later transfer test refused access to another website path. The FTP account does not become an SSH/SFTP account automatically.<br />
<br />
Before sending credentials, configure a certificate matching the hostname you connect to and require FTPS. Our lab used a valid mail.adminslab.com certificate, strict TLS mode 3, and certificate-verified TLS 1.3. A plaintext connection was refused. The separate FTPS guide explains that configuration; the plain ftp:// address displayed by the panel is not an instruction to send a password without encryption.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Verify a real transfer</span><br />
Test an encrypted login, a directory listing, a small original upload and a download of the same file. Compare the bytes or checksum, and confirm the account cannot leave its assigned root.<br />
<br />
Our restricted test account uploaded and downloaded an original AdminsForum text file with matching SHA-256, using protected data connections. The test was performed with a certificate-verifying FTPS client in the lab; it is separate from the panel's service badge.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Common failures</span><ul class="mycode_list"><li>Service will not start: inspect the configuration/error result and existing listeners on the control port.<br />
</li>
<li>Login fails: confirm the account is enabled, the username/password are correct and the client requires explicit FTP over TLS.<br />
</li>
<li>Listing stalls: check passive mode, the configured passive range, server/provider firewall and public address/NAT settings.<br />
</li>
<li>Certificate fails validation: fix the hostname/certificate/chain instead of permanently accepting an unrelated certificate.<br />
</li>
</ul>
<br />
Reference: <a href="https://www.aapanel.com/docs/Function/Ftp.html" target="_blank" rel="noopener" class="mycode_url">aaPanel FTP documentation</a>. © AdminsForum.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
Use aaPanel App Store to install Pure-FTPd if it is missing. Then open its Setting → Service page, confirm the service is started and configure a separate restricted account plus FTPS before using it for website transfers. Installing an FTP server does not automatically prove that a client can log in or transfer files securely.<br />
<br />
Our lab ran aaPanel 8.0.6 on Ubuntu 22.04 with Pure-FTPd 1.0.49. This walkthrough verifies the existing installation, native service start and subsequent encrypted connection checks. The download/reinstallation step was not repeated on the already installed service.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Decide whether you need FTP</span><br />
Pure-FTPd supplies FTP and FTPS. FTPS adds TLS encryption to the FTP protocol. SFTP is a different protocol supplied through SSH; installing Pure-FTPd is not required for SFTP.<br />
<br />
Use a dedicated FTP account when you want to limit a transfer user to an assigned directory without giving them the server's root SSH login. FTP credentials that can modify website files are still sensitive: those files can change the site's behavior.<br />
<br />
Keep existing administrator access working while setting up a new transfer method. Record the current service configuration and firewall rules before changing them. We preserved private configuration copies on the disposable lab.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Find Pure-FTPd in the App Store</span><br />
Open App Store → Official App. Search for Pure-FTPd or use the Deployment category. If it is not installed, use the official row's Install action, review the offered version/method and confirm the installation. Wait for the installation task to finish and inspect any error rather than repeatedly clicking Install.<br />
<br />
If Installed already shows Pure-FTPd with Setting and Uninstall, open Setting. Do not uninstall a functioning transfer service merely to follow the fresh-install branch of a tutorial.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=109" target="_blank" title="">batch11-ftp-installed-branded.jpg</a> (Size: 252.74 KB / Downloads: 9)
<!-- end: postbit_attachments_attachment --><br />
<br />
Our installed list showed Pure-FTPd 1.0.49. Versions and available packages depend on the operating system and current aaPanel catalog. Record the installed version rather than treating an example version number as a permanent recommendation.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Check and start the service</span><br />
Open Pure-FTPd → Setting → Service. If it is stopped, click Start, review the service confirmation and Confirm. Wait for completion, then reopen or refresh the manager and verify Current state is Start and the action has changed to Stop.<br />
<br />
The lab's native service view showed that started state. The same menu exposes configuration, user management, port settings and logs.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=110" target="_blank" title="">batch11-ftp-service-branded.jpg</a> (Size: 82.42 KB / Downloads: 9)
<!-- end: postbit_attachments_attachment --><br />
<br />
A started service is only the first check. If Start fails, inspect its error/configuration result and port conflicts. Do not disable the firewall or stop unrelated web/SSH services to get past an FTP error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Understand control and passive data connections</span><br />
The panel displayed a control address on TCP port 21. Our actual Pure-FTPd configuration used passive data ports 39000–40000. FTP uses a control connection for commands and separate data connections for listings and file transfers, so a successful login with a stalled listing often points to the data path.<br />
<br />
Inspect the configured range before writing firewall rules. The system firewall and any provider firewall must allow the required control/data traffic for the intended clients. Our lab already had its FTP rules; no new public ports were opened during this test. Do not copy an arbitrary passive range that differs from the running service.<br />
<br />
For a private workflow, restrict source addresses where practical. Do not expose database, Redis or internal web-server backend ports as part of FTP setup.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Create the account and secure the connection</span><br />
Open the FTP module and use Add FTP. Assign a unique user to the exact required document root, not /www/wwwroot or a server-wide folder. Use a strong unique password and keep it out of screenshots and tutorial text.<br />
<br />
We created af_ftp_lab only under /www/wwwroot/adminslab.com/ftp-lab. The later transfer test refused access to another website path. The FTP account does not become an SSH/SFTP account automatically.<br />
<br />
Before sending credentials, configure a certificate matching the hostname you connect to and require FTPS. Our lab used a valid mail.adminslab.com certificate, strict TLS mode 3, and certificate-verified TLS 1.3. A plaintext connection was refused. The separate FTPS guide explains that configuration; the plain ftp:// address displayed by the panel is not an instruction to send a password without encryption.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Verify a real transfer</span><br />
Test an encrypted login, a directory listing, a small original upload and a download of the same file. Compare the bytes or checksum, and confirm the account cannot leave its assigned root.<br />
<br />
Our restricted test account uploaded and downloaded an original AdminsForum text file with matching SHA-256, using protected data connections. The test was performed with a certificate-verifying FTPS client in the lab; it is separate from the panel's service badge.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Common failures</span><ul class="mycode_list"><li>Service will not start: inspect the configuration/error result and existing listeners on the control port.<br />
</li>
<li>Login fails: confirm the account is enabled, the username/password are correct and the client requires explicit FTP over TLS.<br />
</li>
<li>Listing stalls: check passive mode, the configured passive range, server/provider firewall and public address/NAT settings.<br />
</li>
<li>Certificate fails validation: fix the hostname/certificate/chain instead of permanently accepting an unrelated certificate.<br />
</li>
</ul>
<br />
Reference: <a href="https://www.aapanel.com/docs/Function/Ftp.html" target="_blank" rel="noopener" class="mycode_url">aaPanel FTP documentation</a>. © AdminsForum.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Install FTP Server in aaPanel Free Edition]]></title>
			<link>https://adminsforum.com/Thread-guide-install-ftp-server-in-aapanel-free-edition</link>
			<pubDate>Sat, 10 Oct 2026 23:30:31 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-install-ftp-server-in-aapanel-free-edition</guid>
			<description><![CDATA[aaPanel Free Edition offers Pure-FTPd for applications or workflows that need FTP accounts. It is optional: you can use the panel File Manager or SSH-based SFTP without installing an FTP server. This guide covers Pure-FTPd installation and its service controls.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested environment</span><br />
Ubuntu 22.04.5 and aaPanel Free Edition 8.0.6. Pure-FTPd 1.0.49 was installed with our initial stack. On 10 October 2026 its panel management screen showed a running service. We have not yet created a dedicated FTP user or verified a file transfer/TLS session, so those results are not claimed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Install Pure-FTPd</span><br />
Open <span style="font-weight: bold;" class="mycode_b">App Store</span>, search for <span style="font-weight: bold;" class="mycode_b">Pure-Ftpd</span> and choose <span style="font-weight: bold;" class="mycode_b">Install</span> if it is absent. Follow the installation dialog and wait for the task to complete. Then open <span style="font-weight: bold;" class="mycode_b">Installed → Pure-Ftpd → Setting</span>. If you already installed FTP with the first-login stack, continue to verification.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check the service controls</span><br />
In our screenshot, <span style="font-weight: bold;" class="mycode_b">1</span> marks the service state, <span style="font-weight: bold;" class="mycode_b">2</span> marks Stop/Restart/Reload and <span style="font-weight: bold;" class="mycode_b">3</span> marks User management. The private lab address is hidden. A running server is only the first check; it does not prove that an account can connect or transfer files.<br />
<img src="https://adminsforum.com/attachment.php?aid=11" loading="lazy"  alt="[Image: attachment.php?aid=11]" class="mycode_img" /><br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Plan a limited account</span><br />
When setting up transfers, use the panel's <span style="font-weight: bold;" class="mycode_b">FTP</span> section or User management. Give each account a strong unique password and restrict its home directory to the intended website files. Avoid sharing root or panel credentials with another person's FTP client. Account creation and a complete transfer test will be a separate guide.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">FTP, FTPS and SFTP</span><br />
Plain FTP does not encrypt its connection. FTPS adds TLS to FTP; SFTP is a different protocol provided through SSH. Installing Pure-FTPd does not turn SSH into FTP or establish that FTPS is configured correctly. For an existing SSH account, SFTP is often the simpler choice; verify the SSH host key before connecting.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting a future transfer</span><br />
A login failure requires checking the FTP user and password. A successful login followed by a directory-listing timeout can involve passive-mode ports and firewall rules. Configure only the necessary ranges after confirming the server/client settings; do not disable the firewall to make a transfer work. Permission errors require checking the account's allowed directory and file ownership.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Next step</span><br />
Decide whether you need FTP at all. Before relying on it, verify an encrypted connection and upload/download a harmless test file using a dedicated account. Keep installation and transfer verification as separate checks.<br />
<br />
<a href="https://adminsforum.com/Thread-guide-install-aapanel-free-edition-on-ubuntu-22-04" target="_blank" rel="noopener" class="mycode_url">Install aaPanel Free Edition on Ubuntu 22.04</a><br />
<a href="https://adminsforum.com/Thread-guide-aapanel-free-edition-install-nginx-php-mariadb" target="_blank" rel="noopener" class="mycode_url">Web stack setup and tutorial series</a><br />
<a href="https://adminsforum.com/Thread-guide-secure-aapanel-free-edition-https-ssh-keys-panel-port" target="_blank" rel="noopener" class="mycode_url">Secure aaPanel Free Edition</a><br />
<br />
<a href="https://www.aapanel.com/docs/Function/AppStore.html" target="_blank" rel="noopener" class="mycode_url">Official aaPanel App Store documentation</a><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=11" target="_blank" title="">ftp-annotated-20261010.jpg</a> (Size: 53.8 KB / Downloads: 9)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[aaPanel Free Edition offers Pure-FTPd for applications or workflows that need FTP accounts. It is optional: you can use the panel File Manager or SSH-based SFTP without installing an FTP server. This guide covers Pure-FTPd installation and its service controls.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested environment</span><br />
Ubuntu 22.04.5 and aaPanel Free Edition 8.0.6. Pure-FTPd 1.0.49 was installed with our initial stack. On 10 October 2026 its panel management screen showed a running service. We have not yet created a dedicated FTP user or verified a file transfer/TLS session, so those results are not claimed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Install Pure-FTPd</span><br />
Open <span style="font-weight: bold;" class="mycode_b">App Store</span>, search for <span style="font-weight: bold;" class="mycode_b">Pure-Ftpd</span> and choose <span style="font-weight: bold;" class="mycode_b">Install</span> if it is absent. Follow the installation dialog and wait for the task to complete. Then open <span style="font-weight: bold;" class="mycode_b">Installed → Pure-Ftpd → Setting</span>. If you already installed FTP with the first-login stack, continue to verification.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check the service controls</span><br />
In our screenshot, <span style="font-weight: bold;" class="mycode_b">1</span> marks the service state, <span style="font-weight: bold;" class="mycode_b">2</span> marks Stop/Restart/Reload and <span style="font-weight: bold;" class="mycode_b">3</span> marks User management. The private lab address is hidden. A running server is only the first check; it does not prove that an account can connect or transfer files.<br />
<img src="https://adminsforum.com/attachment.php?aid=11" loading="lazy"  alt="[Image: attachment.php?aid=11]" class="mycode_img" /><br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Plan a limited account</span><br />
When setting up transfers, use the panel's <span style="font-weight: bold;" class="mycode_b">FTP</span> section or User management. Give each account a strong unique password and restrict its home directory to the intended website files. Avoid sharing root or panel credentials with another person's FTP client. Account creation and a complete transfer test will be a separate guide.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">FTP, FTPS and SFTP</span><br />
Plain FTP does not encrypt its connection. FTPS adds TLS to FTP; SFTP is a different protocol provided through SSH. Installing Pure-FTPd does not turn SSH into FTP or establish that FTPS is configured correctly. For an existing SSH account, SFTP is often the simpler choice; verify the SSH host key before connecting.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting a future transfer</span><br />
A login failure requires checking the FTP user and password. A successful login followed by a directory-listing timeout can involve passive-mode ports and firewall rules. Configure only the necessary ranges after confirming the server/client settings; do not disable the firewall to make a transfer work. Permission errors require checking the account's allowed directory and file ownership.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Next step</span><br />
Decide whether you need FTP at all. Before relying on it, verify an encrypted connection and upload/download a harmless test file using a dedicated account. Keep installation and transfer verification as separate checks.<br />
<br />
<a href="https://adminsforum.com/Thread-guide-install-aapanel-free-edition-on-ubuntu-22-04" target="_blank" rel="noopener" class="mycode_url">Install aaPanel Free Edition on Ubuntu 22.04</a><br />
<a href="https://adminsforum.com/Thread-guide-aapanel-free-edition-install-nginx-php-mariadb" target="_blank" rel="noopener" class="mycode_url">Web stack setup and tutorial series</a><br />
<a href="https://adminsforum.com/Thread-guide-secure-aapanel-free-edition-https-ssh-keys-panel-port" target="_blank" rel="noopener" class="mycode_url">Secure aaPanel Free Edition</a><br />
<br />
<a href="https://www.aapanel.com/docs/Function/AppStore.html" target="_blank" rel="noopener" class="mycode_url">Official aaPanel App Store documentation</a><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=11" target="_blank" title="">ftp-annotated-20261010.jpg</a> (Size: 53.8 KB / Downloads: 9)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
	</channel>
</rss>