{"id":21035,"date":"2024-02-20T12:00:03","date_gmt":"2024-02-20T20:00:03","guid":{"rendered":"https:\/\/portasftpserver.com\/?p=21035"},"modified":"2026-06-22T16:06:12","modified_gmt":"2026-06-22T23:06:12","slug":"best-opensource-sftp-server-libraries","status":"publish","type":"post","link":"https:\/\/portasftpserver.com\/best-opensource-sftp-server-libraries\/","title":{"rendered":"Best Open Source SFTP Server Libraries"},"content":{"rendered":"\n<p class=\"sera-block-paragraph\">As an IT professional looking for SFTP Sever that helps transfer files securely can be frustrating, when you key the word &#8220;Free&#8221; this leads you to different software that can be hard to use and navigate. If you have encountered the latter, then you came to the right place because this blog will show how you can (your team) start building your own SFTP Server using the best Opensource library. Note that the following are the most well-known software \/ libraries.<\/p>\n\n\n\n<h2 class=\"sera-block-heading klc-block-heading\"><a href=\"https:\/\/github.com\/apache\/mina-sshd\" data-type=\"link\" data-id=\"https:\/\/github.com\/apache\/mina-sshd\" target=\"_blank\" rel=\"noreferrer noopener\">Apache Mina SSHD<\/a><\/h2>\n\n\n\n<p class=\"sera-block-paragraph\">Apache MINA SSHD is an open-source library for Java that supports the SSH version 2 protocol. This library supports both the client and server side for file transfer. Besides that, this is under Apache License 2.0 which is good for business usage as it is less restrictive and does not require you to open-source your project (if you want to stay closed-source). Note that there is an <a href=\"https:\/\/portasftpserver.github.io\/ApacheMinaSSHD.NET\/\" data-type=\"link\" data-id=\"https:\/\/portasftpserver.github.io\/ApacheMinaSSHD.NET\/\" target=\"_blank\" rel=\"noreferrer noopener\">Open-source .NET Wrapper for Apache Mina SSHD<\/a>.<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><em>Maven<\/em><\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro klc-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&lt;dependency>\n   &lt;groupId>org.apache.mina&lt;\/groupId>\n   &lt;artifactId>mina-core&lt;\/artifactId>\n   &lt;version>2.0.23&lt;\/version>\n&lt;\/dependency>\n&lt;dependency>\n   &lt;groupId>org.apache.sshd&lt;\/groupId>\n   &lt;artifactId>sshd-core&lt;\/artifactId>\n   &lt;version>2.13.0-SNAPSHOT&lt;\/version>\n&lt;\/dependency><\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #56B6C2\">&lt;<\/span><span style=\"color: #E06C75\">dependency<\/span><span style=\"color: #56B6C2\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E06C75\">   <\/span><span style=\"color: #56B6C2\">&lt;<\/span><span style=\"color: #E06C75\">groupId<\/span><span style=\"color: #56B6C2\">&gt;<\/span><span style=\"color: #E5C07B\">org<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E5C07B\">apache<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E5C07B\">mina<\/span><span style=\"color: #56B6C2\">&lt;\/<\/span><span style=\"color: #E06C75\">groupId<\/span><span style=\"color: #56B6C2\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E06C75\">   <\/span><span style=\"color: #56B6C2\">&lt;<\/span><span style=\"color: #E06C75\">artifactId<\/span><span style=\"color: #56B6C2\">&gt;<\/span><span style=\"color: #E06C75\">mina<\/span><span style=\"color: #56B6C2\">-<\/span><span style=\"color: #E06C75\">core<\/span><span style=\"color: #56B6C2\">&lt;\/<\/span><span style=\"color: #E06C75\">artifactId<\/span><span style=\"color: #56B6C2\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E06C75\">   <\/span><span style=\"color: #56B6C2\">&lt;<\/span><span style=\"color: #E06C75\">version<\/span><span style=\"color: #56B6C2\">&gt;<\/span><span style=\"color: #D19A66\">2.0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #FFFFFF\">23<\/span><span style=\"color: #56B6C2\">&lt;\/<\/span><span style=\"color: #E06C75\">version<\/span><span style=\"color: #56B6C2\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #56B6C2\">&lt;\/<\/span><span style=\"color: #E06C75\">dependency<\/span><span style=\"color: #56B6C2\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #56B6C2\">&lt;<\/span><span style=\"color: #E06C75\">dependency<\/span><span style=\"color: #56B6C2\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E06C75\">   <\/span><span style=\"color: #56B6C2\">&lt;<\/span><span style=\"color: #E06C75\">groupId<\/span><span style=\"color: #56B6C2\">&gt;<\/span><span style=\"color: #E5C07B\">org<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E5C07B\">apache<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E5C07B\">sshd<\/span><span style=\"color: #56B6C2\">&lt;\/<\/span><span style=\"color: #E06C75\">groupId<\/span><span style=\"color: #56B6C2\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E06C75\">   <\/span><span style=\"color: #56B6C2\">&lt;<\/span><span style=\"color: #E06C75\">artifactId<\/span><span style=\"color: #56B6C2\">&gt;<\/span><span style=\"color: #E06C75\">sshd<\/span><span style=\"color: #56B6C2\">-<\/span><span style=\"color: #E06C75\">core<\/span><span style=\"color: #56B6C2\">&lt;\/<\/span><span style=\"color: #E06C75\">artifactId<\/span><span style=\"color: #56B6C2\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E06C75\">   <\/span><span style=\"color: #56B6C2\">&lt;<\/span><span style=\"color: #E06C75\">version<\/span><span style=\"color: #56B6C2\">&gt;<\/span><span style=\"color: #D19A66\">2.13<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #FFFFFF\">0<\/span><span style=\"color: #56B6C2\">-<\/span><span style=\"color: #E5C07B\">SNAPSHOT<\/span><span style=\"color: #56B6C2\">&lt;\/<\/span><span style=\"color: #E06C75\">version<\/span><span style=\"color: #56B6C2\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #56B6C2\">&lt;\/<\/span><span style=\"color: #E06C75\">dependency<\/span><span style=\"color: #56B6C2\">&gt;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><em>Imports<\/em><\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers klc-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>import org.apache.sshd.server.SshServer;\nimport org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;\nimport org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory;<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C678DD\">import<\/span><span style=\"color: #E06C75\"> <\/span><span style=\"color: #E5C07B\">org.apache.sshd.server.SshServer<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">import<\/span><span style=\"color: #E06C75\"> <\/span><span style=\"color: #E5C07B\">org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">import<\/span><span style=\"color: #E06C75\"> <\/span><span style=\"color: #E5C07B\">org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><em>Main code<\/em><\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers klc-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:3;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var sshd = SshServer.setUpDefaultServer();\nsshd.setHost(\"127.0.0.1\");\nsshd.setPort(22) \/\/ if linux try 2222;\nsshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());\nsshd.setPasswordAuthenticator((username, password, session) -> {\n     \n\/\/ can also set the based home dir\n\/\/ fileSystemFactory.setDefaultHomeDir(\"C:\/SFTPUsers\");\n\n  if (username.equals(\"john\") &amp;&amp; password.equals(\"passwordSecret\"))\n  {\n         VirtualFileSystemFactory fileSystemFactory = new VirtualFileSystemFactory();\n         \/\/ sample of mapping each user to desired root dir\n         fileSystemFactory.setUserHomeDir(username.toLowerCase(), \"JohnRootDir\");\n         sshd.setFileSystemFactory(fileSystemFactory)\n         return true;\n   }\n      \n});\n\nsshd.start();<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C678DD\">var<\/span><span style=\"color: #E06C75\"> sshd <\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #E06C75\"> <\/span><span style=\"color: #E5C07B\">SshServer<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">setUpDefaultServer<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E5C07B\">sshd<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">setHost<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;127.0.0.1&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E5C07B\">sshd<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">setPort<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #D19A66\">22<\/span><span style=\"color: #ABB2BF\">)<\/span><span style=\"color: #E06C75\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ if linux try 2222;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E5C07B\">sshd<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">setKeyPairProvider<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #C678DD\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">SimpleGeneratorHostKeyProvider<\/span><span style=\"color: #ABB2BF\">());<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E5C07B\">sshd<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">setPasswordAuthenticator<\/span><span style=\"color: #ABB2BF\">((username, password, session) <\/span><span style=\"color: #C678DD\">-&gt;<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ can also set the based home dir<\/span><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ fileSystemFactory.setDefaultHomeDir(&quot;C:\/SFTPUsers&quot;);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #E5C07B\">username<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">equals<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;john&quot;<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #56B6C2\">&amp;&amp;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">password<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">equals<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;passwordSecret&quot;<\/span><span style=\"color: #ABB2BF\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">         <\/span><span style=\"color: #E5C07B\">VirtualFileSystemFactory<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E06C75\">fileSystemFactory<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">VirtualFileSystemFactory<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">         <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ sample of mapping each user to desired root dir<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">         <\/span><span style=\"color: #E5C07B\">fileSystemFactory<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">setUserHomeDir<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #E5C07B\">username<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">toLowerCase<\/span><span style=\"color: #ABB2BF\">(), <\/span><span style=\"color: #98C379\">&quot;JohnRootDir&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">         <\/span><span style=\"color: #E5C07B\">sshd<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">setFileSystemFactory<\/span><span style=\"color: #ABB2BF\">(fileSystemFactory)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">         <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">true<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">      <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">});<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E5C07B\">sshd<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">start<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><em>Note.<\/em> This is adapted from <a href=\"https:\/\/github.com\/apache\/mina-sshd\/blob\/master\/docs\/server-setup.md\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/apache\/mina-sshd\/blob\/master\/docs\/server-setup.md<\/a><\/p>\n\n\n\n<p style=\"font-size:24px; line-height: 1.6;\"><strong>Fun fact<\/strong>, <a href=\"https:\/\/portasftpserver.com\/portable-sftp-server-community-edition\/\" data-type=\"page\" data-id=\"8937\" target=\"_blank\" rel=\"noreferrer noopener\">Porta SFTP Server Free\/Pro Edition<\/a> is created in Java and uses the pure Java Apache Mina library..<\/p>\n\n\n\n<h2 class=\"sera-block-heading klc-block-heading\"><a href=\"https:\/\/github.com\/ronf\/asyncssh\" data-type=\"link\" data-id=\"https:\/\/github.com\/ronf\/asyncssh\" target=\"_blank\" rel=\"noreferrer noopener\">AsyncSSH<\/a><\/h2>\n\n\n\n<p class=\"sera-block-paragraph\">AsyncSSH supports asynchronous client and server implementation of the SSH version 2 protocol and adapted the <strong>Python 3.6+<\/strong> asyncio framework.<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><em>Sample Code<\/em><\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers klc-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>import asyncio, asyncssh, sys from typing import Optional\n\n# user credentials collections\ncredentials = {'TestUser1': 'credentialsecret'}\n\ndef client_handler(process: asyncssh.SSHServerProcess) -> None:\n    process.stdout.write('Welcome to AsyncSSH server,' + process.get_extra_info('username') + '\\n')\n    process.exit(0)\n\nclass SSHDServer(asyncssh.SSHServer):\n    def connection_made(self, con: asyncssh.SSHServerConnection) -> None:\n        # see the received information and its client address\n        print('Connection received from' + con.get_extra_info('peername')&#91;0&#93;)\n\n    def password_auth_supported(self) -> bool:\n        return True #feel free to adjust\n        \n    def begin_auth(self, username: str) -> bool:\n        return credentials.get(username) != ''\n\n    def connection_lost(self, exc: Optional&#91;Exception&#93;) -> None:\n        if exc:\n            print('Connection exception\/error: ' + str(exc), file=sys.stderr)\n        else:\n            print('Connection closed.')\n\n    def validate_password(self, username: str, password: str) -> bool:\n        userPassword = credentials.get(username, '*')\n        return password == userPassword # check if match, feel free to use cryptography\n\nasync def start_server() -> None:\n    await asyncssh.create_server(SSHDServer, '', 22,\n                                 server_host_keys=&#91;'your_host_key'&#93;,\n                                 process_factory=client_handler)\n\nproc = asyncio.get_event_loop()\n\ntry:\n    proc.run_until_complete(start_server())\nexcept (OSError, asyncssh.Error) as exception:\n    sys.exit('Error occured when starting the server: ' + str(exception))\n\nproc.run_forever()<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C678DD\">import<\/span><span style=\"color: #ABB2BF\"> asyncio, asyncssh, sys <\/span><span style=\"color: #C678DD\">from<\/span><span style=\"color: #ABB2BF\"> typing <\/span><span style=\"color: #C678DD\">import<\/span><span style=\"color: #ABB2BF\"> Optional<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># user credentials collections<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">credentials <\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #ABB2BF\"> {<\/span><span style=\"color: #98C379\">&#39;TestUser1&#39;<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #98C379\">&#39;credentialsecret&#39;<\/span><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">def<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">client_handler<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #D19A66; font-style: italic\">process<\/span><span style=\"color: #ABB2BF\">: asyncssh.SSHServerProcess) -&gt; <\/span><span style=\"color: #D19A66\">None<\/span><span style=\"color: #ABB2BF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    process.stdout.<\/span><span style=\"color: #61AFEF\">write<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&#39;Welcome to AsyncSSH server,&#39;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">+<\/span><span style=\"color: #ABB2BF\"> process.<\/span><span style=\"color: #61AFEF\">get_extra_info<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&#39;username&#39;<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #56B6C2\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&#39;<\/span><span style=\"color: #56B6C2\">\\n<\/span><span style=\"color: #98C379\">&#39;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    process.<\/span><span style=\"color: #61AFEF\">exit<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">class<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">SSHDServer<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #E5C07B\">asyncssh<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E5C07B\">SSHServer<\/span><span style=\"color: #ABB2BF\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">def<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">connection_made<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #E5C07B; font-style: italic\">self<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #D19A66; font-style: italic\">con<\/span><span style=\"color: #ABB2BF\">: asyncssh.SSHServerConnection) -&gt; <\/span><span style=\"color: #D19A66\">None<\/span><span style=\"color: #ABB2BF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\"># see the received information and its client address<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&#39;Connection received from&#39;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">+<\/span><span style=\"color: #ABB2BF\"> con.<\/span><span style=\"color: #61AFEF\">get_extra_info<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&#39;peername&#39;<\/span><span style=\"color: #ABB2BF\">)&#91;<\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">&#93;)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">def<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">password_auth_supported<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #E5C07B; font-style: italic\">self<\/span><span style=\"color: #ABB2BF\">) -&gt; <\/span><span style=\"color: #56B6C2\">bool<\/span><span style=\"color: #ABB2BF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">True<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">#feel free to adjust<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">def<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">begin_auth<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #E5C07B; font-style: italic\">self<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #D19A66; font-style: italic\">username<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #56B6C2\">str<\/span><span style=\"color: #ABB2BF\">) -&gt; <\/span><span style=\"color: #56B6C2\">bool<\/span><span style=\"color: #ABB2BF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> credentials.<\/span><span style=\"color: #61AFEF\">get<\/span><span style=\"color: #ABB2BF\">(username) <\/span><span style=\"color: #56B6C2\">!=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&#39;&#39;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">def<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">connection_lost<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #E5C07B; font-style: italic\">self<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #D19A66; font-style: italic\">exc<\/span><span style=\"color: #ABB2BF\">: Optional&#91;Exception&#93;) -&gt; <\/span><span style=\"color: #D19A66\">None<\/span><span style=\"color: #ABB2BF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> exc:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&#39;Connection exception\/error: &#39;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">str<\/span><span style=\"color: #ABB2BF\">(exc), <\/span><span style=\"color: #E06C75; font-style: italic\">file<\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #ABB2BF\">sys.stderr)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&#39;Connection closed.&#39;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">def<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">validate_password<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #E5C07B; font-style: italic\">self<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #D19A66; font-style: italic\">username<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #56B6C2\">str<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #D19A66; font-style: italic\">password<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #56B6C2\">str<\/span><span style=\"color: #ABB2BF\">) -&gt; <\/span><span style=\"color: #56B6C2\">bool<\/span><span style=\"color: #ABB2BF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        userPassword <\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #ABB2BF\"> credentials.<\/span><span style=\"color: #61AFEF\">get<\/span><span style=\"color: #ABB2BF\">(username, <\/span><span style=\"color: #98C379\">&#39;*&#39;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> password <\/span><span style=\"color: #56B6C2\">==<\/span><span style=\"color: #ABB2BF\"> userPassword <\/span><span style=\"color: #7F848E; font-style: italic\"># check if match, feel free to use cryptography<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">async<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">def<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">start_server<\/span><span style=\"color: #ABB2BF\">() -&gt; <\/span><span style=\"color: #D19A66\">None<\/span><span style=\"color: #ABB2BF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">await<\/span><span style=\"color: #ABB2BF\"> asyncssh.<\/span><span style=\"color: #61AFEF\">create_server<\/span><span style=\"color: #ABB2BF\">(SSHDServer, <\/span><span style=\"color: #98C379\">&#39;&#39;<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #D19A66\">22<\/span><span style=\"color: #ABB2BF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                 <\/span><span style=\"color: #E06C75; font-style: italic\">server_host_keys<\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #ABB2BF\">&#91;<\/span><span style=\"color: #98C379\">&#39;your_host_key&#39;<\/span><span style=\"color: #ABB2BF\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                 <\/span><span style=\"color: #E06C75; font-style: italic\">process_factory<\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #ABB2BF\">client_handler)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">proc <\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #ABB2BF\"> asyncio.<\/span><span style=\"color: #61AFEF\">get_event_loop<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">try<\/span><span style=\"color: #ABB2BF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    proc.<\/span><span style=\"color: #61AFEF\">run_until_complete<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">start_server<\/span><span style=\"color: #ABB2BF\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">except<\/span><span style=\"color: #ABB2BF\"> (OSError, asyncssh.Error) <\/span><span style=\"color: #C678DD\">as<\/span><span style=\"color: #ABB2BF\"> exception:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    sys.<\/span><span style=\"color: #61AFEF\">exit<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&#39;Error occured when starting the server: &#39;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">str<\/span><span style=\"color: #ABB2BF\">(exception))<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">proc.<\/span><span style=\"color: #61AFEF\">run_forever<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><em>Note.<\/em> Code adapted from <a href=\"https:\/\/asyncssh.readthedocs.io\/en\/latest\/#simple-server\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/asyncssh.readthedocs.io\/en\/latest\/#simple-server<\/a><\/p>\n\n\n\n<p class=\"sera-block-paragraph\">Another alternative for AsyncSSH is the <a href=\"https:\/\/github.com\/paramiko\/paramiko\" data-type=\"link\" data-id=\"https:\/\/github.com\/paramiko\/paramiko\" target=\"_blank\" rel=\"noreferrer noopener\">Paramiko<\/a> which only supports a single threaded processing by default. However, the two are very similar as both are made in Python programming language. An example of using SFTP Server with Paramiko can be located on its GitHub repo at <a href=\"https:\/\/github.com\/paramiko\/paramiko\/blob\/main\/demos\/demo_server.py\">https:\/\/github.com\/paramiko\/paramiko\/blob\/main\/demos\/demo_server.py<\/a>. <\/p>\n\n\n\n<h2 class=\"sera-block-heading klc-block-heading\"><a href=\"https:\/\/github.com\/drakkan\/sftpgo\" data-type=\"link\" data-id=\"https:\/\/github.com\/drakkan\/sftpgo\" target=\"_blank\" rel=\"noreferrer noopener\">SFTPGo<\/a><\/h2>\n\n\n\n<p class=\"sera-block-paragraph\">Probably one of the best today is the SFTPGo Server, which is good for business use. This open-source product has web-based administration by default and supports notable functionalities such as allowing you to make API calls for automation etc. <\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Multiple protocols: SFTP, FTPS, HTTPS, WebDAV.<\/li>\n\n\n\n<li>Multiple storage backends: local filesystem, encrypted local filesystem, S3, Google Cloud Storage, Azure Blob Storage, and SFTP.<\/li>\n\n\n\n<li>Custom workflows based on server events or schedules.<\/li>\n\n\n\n<li>Multi-factor and multi-step authentication.<\/li>\n\n\n\n<li>Public key and password authentication. Multiple public keys per user are supported.<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><em>Note.<\/em> To learn more about the SFTPGo go to <a href=\"https:\/\/github.com\/drakkan\/sftpgo\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/drakkan\/sftpgo<\/a>.<\/p>\n\n\n\n<h2 class=\"sera-block-heading klc-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"sera-block-paragraph\">So, this blog tackles one of the best Opens Source SFTP Server libraries and Software on the internet today. However, choosing the right product is still your (company&#8217;s) decision that aligns with the reason\/s to have such an SFTP Server for file transfer or data exchange. That said, if your company is okay using such as Free and Opensource software (that may have limited support) then go for it, if not then look for other solutions that align with business compliance and its purpose in the long run.<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>As an IT professional looking for SFTP Sever that helps transfer files securely can be frustrating, when you key the word &#8220;Free&#8221; this leads you to different software that can be hard to use and navigate. If you have encountered the latter, then you came to the right place because this blog will show how [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":21037,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[306,124,189,1],"tags":[274,310,272,278,358,357,301,300,359,269,275,210,276,277,299,270,297,302,309,308,280,296,273,271,295,279],"class_list":["post-21035","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cybersecurity-for-critical-infrastructure","category-data-information-security","category-free-software","category-programming-software","tag-apache-mina-sftp-server","tag-apache-mina-sshd-sample","tag-asyncssh-sftp-server","tag-best-net-sftp-server-libraries","tag-best-net-sftp-server-libraries-that-open-source","tag-best-net-sftp-server-library","tag-best-free-sftp-server","tag-best-free-sftp-server-for-windows","tag-best-open-source-net-sftp-server-libraries","tag-best-opensource-sftp-server","tag-best-opensource-sftp-server-libraries","tag-best-portable-sftp-server","tag-best-rebex-alternative","tag-best-rebex-net-alternative","tag-best-sftp-server-for-windows","tag-best-sftp-server-library","tag-buru-sftp-server-alternative","tag-free-sftp-server","tag-how-to-create-sftp-server-with-apache-mina","tag-how-to-use-apache-mina-sshd","tag-networking-java-libraries","tag-nsoftware-alternative","tag-paramiko-sftp-server","tag-sftp-server-development","tag-tiny-sftp-server-alternative","tag-well-maintained-sftp-server-libraries"],"_links":{"self":[{"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/posts\/21035","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/comments?post=21035"}],"version-history":[{"count":117,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/posts\/21035\/revisions"}],"predecessor-version":[{"id":26191,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/posts\/21035\/revisions\/26191"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/media\/21037"}],"wp:attachment":[{"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/media?parent=21035"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/categories?post=21035"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/tags?post=21035"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}