An FTPS certificate mismatch is fixed by the name you dial
Shared hosting FTP certificates usually cover the server node, not ftp.<your-domain>. Read the certificate, connect by the name it covers, and never turn verification off on a session carrying a password.
You connect to ftp.<your-domain> over FTPS. The login works, and then the
first directory listing fails:
certificate common name doesn't match requested host nameThe usual advice you’ll find is set ssl:verify-certificate no. Please don’t
do that on a session that carries a password. Verification is the only thing
protecting that password from whoever sits in the middle, and that setting
switches it off.
Read the certificate first
The mismatch is telling you something, so look at what the server actually presents:
openssl s_client -connect ftp.<your-domain>:21 -starttls ftp </dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltNameOn shared hosting you’ll usually get a current, valid certificate whose only
name is the hosting node itself, something like cpNNN.<provider>.net, and
ftp.<your-domain> turns out to be a CNAME pointing at that node. There’s
nothing wrong with the certificate. You’re just dialling it by a name it was
never issued for.
Check that both names resolve to the same address, then connect by the node name. Verification passes, you haven’t weakened anything, and it keeps passing after the certificate renews. Use that same name in every deploy script and CI variable that talks to the account. This site’s own pipeline connects that way.
Two lftp habits
Keep the password out of argv. lftp reads ~/.netrc, so running
HOME=<scratch-dir> lftp -u <user> <host> with a netrc in the scratch
directory keeps the password off the command line and out of the process
table. Passwords containing #, $ or @ need no escaping in that file.
Also, dotfiles aren’t listed unless you ask for them. Without
set ftp:list-options -a, a mirror silently skips every dot-directory. That
includes .well-known/, which on shared hosting is often where the account’s
own certificate validation lives, and the mirror still looks complete
afterwards.
Checking a mirror against .ftpquota
cPanel-style hosts keep a .ftpquota file in the FTP root. It holds two
numbers, inodes and bytes, covering everything in the account except the file
itself. So after mirroring the whole account you get an integrity check for
free:
find <mirror> | wc -l # the inode count, plus 1 for .ftpquota
du -sb --apparent-size <mirror> # roughly the byte count, plus .ftpquota's own sizeDirectories count as inodes, which is why this uses find without -type f.
If both numbers line up, you have everything. If they don’t, the difference gives you a rough idea of what’s missing, and in my experience it’s usually a dot-directory.
The paths in the account that need protecting are also the ones a safe
--delete deploy has to exclude.