{"id":75553,"date":"2024-02-20T17:25:54","date_gmt":"2024-02-20T09:25:54","guid":{"rendered":"https:\/\/version-2.com\/?p=75553"},"modified":"2024-02-07T17:33:56","modified_gmt":"2024-02-07T09:33:56","slug":"libdrop-file-sharing-through-nordvpn","status":"publish","type":"post","link":"https:\/\/version-2.com\/zh\/2024\/02\/libdrop-file-sharing-through-nordvpn\/","title":{"rendered":"Libdrop: File sharing through NordVPN"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"75553\" class=\"elementor elementor-75553\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-35fe5dd post-content elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"35fe5dd\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;_id&quot;:&quot;cef08c3&quot;,&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-409a2e9a\" data-id=\"409a2e9a\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-5a8be8f elementor-widget elementor-widget-text-editor\" data-id=\"5a8be8f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<div class=\"max-w-post-content\"><div class=\"block md:hidden\"><div><div class=\"hidden md:block TableOfContents_tocDesktop__9_aoA\">\u00a0<\/div><\/div><\/div><p class=\"text-base leading-normal\">The Libdrop library allows NordVPN users to <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/nordvpn.com\/meshnet\/file-sharing\/\" target=\"_blank\" rel=\"noopener noreferrer\">share files over Meshnet<\/a>. In this article, we explain how we developed our file transfer system and the role Libdrop plays in it.<\/p><p><img fetchpriority=\"high\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2024\/02\/featured-image.png\" width=\"1200\" height=\"675\" \/><\/p><div class=\"style_postContent__uJLGT text-black break-words\" data-content-type-blog=\"true\"><div class=\"Article_wrapper__YyQ2_\"><h2 id=\"What is Libdrop?\" class=\"text-h2 leading-none text-left\"><b>What is Libdrop?<\/b><\/h2><p class=\"text-base leading-normal\">Libdrop is a cross-platform library developed in the Rust programming language. It is compatible with Windows, MacOS, Linux, iOS, and Android. File sharing within the NordVPN environment is facilitated by the Libdrop library, which is available as an open-source resource on <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/github.com\/NordSecurity\/libdrop\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub<\/a>.<\/p><p class=\"text-base leading-normal\">The goal of Libdrop implementation is to allow smooth and secure file sharing between users over Meshnet. The library should be easily integrated into the NordVPN application so API users can issue transfer requests, with the rest of the processes being carried out in the library.<\/p><h2 id=\"Libdrop protocol\" class=\"text-h2 leading-none text-left\"><b>Libdrop protocol<\/b><\/h2><p class=\"text-base leading-normal\">The Libdrop protocol enables peer-to-peer file sharing via both <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/nordvpn.com\/blog\/ipv4-vs-ipv6\/\" target=\"_blank\" rel=\"noopener noreferrer\">IPv4 and IPv6<\/a>. In this process, the sender presents files to the receiver, who then selects specific files for download. Downloads are then initiated.<\/p><p class=\"text-base leading-normal\">The transfer is live until one of the peers goes down or the transfer is explicitly canceled by either of the peers, after which the files are no longer available for download. This provides the user with a time window where they can decide which files they want to download now and in the future while the transfer is still up.<\/p><p><img decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2024\/02\/image-1.png\" width=\"1200\" height=\"1168\" \/><\/p><div class=\"my-64 text-center\"><p class=\"text-nano leading-normal text-left text-center text-gray-600 my-8\">High-level overview of communication between two peers.<\/p><\/div><h2 id=\"Communication and low-level details\" class=\"text-h2 leading-none text-left\"><b>Communication and low-level details<\/b><\/h2><p class=\"text-base leading-normal\">Let\u2019s take a closer look at the technical details of the communication process, and how we developed our current setup.<\/p><p class=\"text-base leading-normal\"><b>gRPC<\/b><\/p><p class=\"text-base leading-normal\">At first glance, it seemed evident that our easiest course of action would be to focus on the HTTP server and client because this is very easy to use and understand, as well as being a time-proven technology. We could make a REST endpoint and just proceed with a regular HTTP download.<\/p><p class=\"text-base leading-normal\">To enhance speed and control, we opted for gRPC. Because gRPC is a binary protocol it has less overhead. It is also strongly typed, making errors harder to introduce. gRPC technology automatically generates the code needed for both the client and the server, making it an excellent fit. In fact, Libdrop was originally built on gRPC.<\/p><p class=\"text-base leading-normal\">Initially, it was very comfortable to use \u2014 both the client and the server code just worked. We could issue a certain call via the wire and expect the appropriate function to be called on the peer.<\/p><p class=\"text-base leading-normal\">However, as time went on, we found that debugging gRPC presented some challenges, and the &#8220;black box&#8221; nature of it began to concern us. The generated code also had little control over the socket itself because it was abstracted too far away to gain direct access. Consequently, we transitioned from gRPC to WebSockets in pursuit of a more adaptable solution.<\/p><p class=\"text-base leading-normal\"><b>WebSockets<\/b><\/p><p class=\"text-base leading-normal\">Unlike gRPC, WebSockets is not strongly typed, which offers a degree of flexibility. This flexibility comes at the cost of making it easier for bugs to appear. However, there&#8217;s no automatic code generation, which is a plus.<\/p><p class=\"text-base leading-normal\">The ability to easily introduce versioning was another advantage. We just need to have the URL in the form of &#8220;ws:\/\/{addr}\/drop\/{version}\/query.&#8221; It also helped that WebSockets is a fairly easy-to-understand technology that works in tandem with HTTP so the traffic can be inspected easily as well as debugged.<\/p><p class=\"text-base leading-normal\">Choosing WebSockets turned out to be a wise decision. It led to a reduction in code complexity and greatly enhanced our understanding of the data flow. Plus, having written the code ourselves, we felt fully in control of the system.<\/p><p><img decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2024\/02\/image-2.png\" width=\"1200\" height=\"889\" \/><\/p><div class=\"my-64 text-center\"><p class=\"text-nano leading-normal text-left text-center text-gray-600 my-8\">Simplified representation of backward compatibility between Libdrop versions.<\/p><\/div><p class=\"text-base leading-normal\"><b>Rust and Tokio<\/b><\/p><p class=\"text-base leading-normal\">Due to the nature of the Libdrop library\u2019s heavy IO and event-driven architecture, the codebase contains a lot of asynchronous flows which could have been a tough problem. However, Rust\u2019s great implementation of async alongside the Tokio library proved to be a great combination in dealing with this and avoiding potential crashes.<\/p><p class=\"text-base leading-normal\">Rust shines because the borrow checker is really persistent about lifetimes and safety while developing because it prevents you from compiling incorrect code that breaks ownership rules.<\/p><p class=\"text-base leading-normal\">We are also fairly safe from panics as we spend most of the time in Tokio tasks and those are <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/doc.rust-lang.org\/std\/panic\/fn.catch_unwind.html\" target=\"_blank\" rel=\"noopener noreferrer\">executed in catch_unwind<\/a>. This means that if the Tokio task panics it will simply yield an error instead of tearing the whole thread down.<\/p><p class=\"text-base leading-normal\">Still, not every place in the codebase runs in a Tokio task, and so for those cases where a Tokio task is not involved, we tune Rust linter to detect unwrap() calls in the codebase that could potentially invoke a panic handler.<\/p><p class=\"text-base leading-normal\">NordVPN uses Rust in numerous libraries and panics are handled in custom panic handlers. These handlers wrap the error and emit it via callback so the API user receives it and can properly log it.<\/p><h2 id=\"API and the dilemma: To block or not to block?\" class=\"text-h2 leading-none text-left\"><b>API and the dilemma: To block or not to block?<\/b><\/h2><p class=\"text-base leading-normal\">We\u2019ll now explore the choices we made around our API.<\/p><p class=\"text-base leading-normal\"><b>SWIG<\/b><\/p><p class=\"text-base leading-normal\">For the API we used SWIG, which was already battle-tested and proven by libraries such as Libtelio. SWIG automatically generates FFI binding code for all target platforms, but it\u2019s not without limitations. While it\u2019s very easy to pass primitives such as integers and strings, higher-order structures are not that comfortable. In a compromise, we accept certain parameters as JSON strings.<\/p><p class=\"text-base leading-normal\">JSON strings, while slightly less optimal, are a great solution to the problem. All mainstream languages know how to parse it or have a popular library ready to do so. The downsides to JSON strings are less type safety and a need for greater control to avoid breaking the conformity.<\/p><p class=\"text-base leading-normal\"><b>Event-driven architecture and reporting<\/b><\/p><p class=\"text-base leading-normal\">One question that arose around the API was whether or not we should block it. Based on the API users we opted to not make the API block and communicate via events. This provides more complexity on the API design side but it provides an event-driven API and means that API users don\u2019t need to care about threads. App developers are usually experienced in working with callbacks so this architecture suits them well.<\/p><p class=\"text-base leading-normal\">Callbacks are used for event notification and reporting so the API user can receive reports and log them where appropriate. Events are for reporting. Both events and reports are passed on as JSON-encoded strings.<\/p><p class=\"text-base leading-normal\">Errors are reported when the parameters to the API are incorrect or when a runtime error is encountered.<\/p><h2 id=\"Types of events\" class=\"text-h2 leading-none text-left\"><b>Types of events<\/b><\/h2><p class=\"text-base leading-normal\">Events are emitted for various milestones:<\/p><p class=\"text-base leading-normal\">A transfer was requested.<\/p><p class=\"text-base leading-normal\">The transfer was successfully queued (the API returned no error) and contains all the paths collected.<\/p><p class=\"text-base leading-normal\">A file upload\/download was started, finished, or failed.<\/p><p class=\"text-base leading-normal\">A file upload or download progressed.<\/p><h2 id=\"User experience and history tracking with SQLite\" class=\"text-h2 leading-none text-left\"><b>User experience and history tracking with SQLite<\/b><\/h2><p class=\"text-base leading-normal\">When considering how to track transfer records and states, our team opted for a local SQLite database that users can easily inspect.<\/p><p class=\"text-base leading-normal\">We chose SQLite for its flexibility and cross-platform availability, and because it offers a strong query system that makes it user-friendly.<\/p><p class=\"text-base leading-normal\">The widespread use of SQLite in various applications gave us added confidence in its reliability and performance, making it an easier choice over alternatives like JSON files or custom binary formats.<\/p><h2 id=\"Database limitations: A read-only resource\" class=\"text-h2 leading-none text-left\"><b>Database limitations: A read-only resource<\/b><\/h2><p class=\"text-base leading-normal\">The SQLite database does not control Libdrop&#8217;s operations in any way. Its role is purely read-only. The SQLite database serves to offer our users a convenient API for accessing transfer histories and logs, without impacting the underlying functionality of Libdrop.<\/p><p class=\"text-base leading-normal\">In cases where we fail to open or migrate the SQLite database successfully we can remove it entirely and try again. If it fails again we can then use an in-memory database that provides proper functionality while the app is alive.<\/p><h2 id=\"Security and validation\" class=\"text-h2 leading-none text-left\"><b>Security and validation<\/b><\/h2><p class=\"text-base leading-normal\">Security in Libdrop has several key focuses:<\/p><ul class=\"list-disc ml-24\"><li class=\"ml-20\"><div><p class=\"text-base leading-normal\">Ensuring that the right sent file reaches the receiver.<\/p><\/div><\/li><li class=\"ml-20\"><div><p class=\"text-base leading-normal\">Ensuring that a transferred file is immediately picked up and scanned by <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/nordvpn.com\/features\/threat-protection\/\" target=\"_blank\" rel=\"noopener noreferrer\">NordVPN\u2019s Threat Protection feature<\/a>.<\/p><\/div><\/li><li class=\"ml-20\"><div><p class=\"text-base leading-normal\">Ensuring that foreign apps cannot make calls directly to the peer.<\/p><\/div><\/li><li class=\"ml-20\"><div><p class=\"text-base leading-normal\">File validation: Ensuring integrity from start to finish<\/p><\/div><\/li><\/ul><p class=\"text-base leading-normal\">As part of our commitment to ensuring a reliable file transfer process, we take several precautions. The moment a file is selected for upload, we immediately fetch its metadata, specifically capturing its size and checksum. This information is then shared with the receiver to ensure both parties have synchronized data right from the start.<\/p><p class=\"text-base leading-normal\">During the actual upload, we keep a close eye on the data transfer. We compare the size of the transferred data with that of the received data, allowing us to detect any inconsistencies. If a discrepancy is found, the transfer is terminated, ensuring that only accurate and complete files proceed.<\/p><p class=\"text-base leading-normal\">At the receiving end, a fresh checksum is calculated once the correct amount of data is received. If this calculated checksum doesn&#8217;t align with the initially shared checksum, the transfer is terminated. In such cases, the transfer is reported and stored as a failed transfer on both ends.<\/p><h2 id=\"Threat Protection\" class=\"text-h2 leading-none text-left\"><b>Threat Protection<\/b><\/h2><p class=\"text-base leading-normal\">In both Windows and MacOS, files often carry metadata indicating their origin. Without this information, <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/nordvpn.com\/features\/threat-protection\/scan-file-for-viruses\/\">antivirus software would need to scan each and every file for threats<\/a>, which isn&#8217;t efficient.<\/p><p class=\"text-base leading-normal\">Applications regularly produce many files, the majority of which are legitimate and harmless so it\u2019s common practice to embed specific markers within these files. This allows antivirus tools to identify and scan files faster.<\/p><p class=\"text-base leading-normal\">On Windows and MacOS, we immediately attach these markers once files are downloaded. This ensures that the Threat Protection scanner can promptly identify and assess them, leaving no gap during which they might be accessed without a prior security check.<\/p><p class=\"text-base leading-normal\">MacOS uses <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/developer.apple.com\/documentation\/coreservices\/kmditemwherefroms\" target=\"_blank\" rel=\"noopener noreferrer\">kMDItemWhereFroms<\/a> while Windows uses <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/learn.microsoft.com\/en-us\/openspecs\/windows_protocols\/ms-fscc\/6e3f7352-d11c-4d76-8c39-2516a9df36e8\" target=\"_blank\" rel=\"noopener noreferrer\">Zone.Identifier<\/a>.<\/p><h2 id=\"Socket security\" class=\"text-h2 leading-none text-left\"><b>Socket security<\/b><\/h2><p class=\"text-base leading-normal\">Finding the protocol and communication method used by Libdrop is straightforward. The port we use is 49111, and the address is in the format ws:\/\/{addr}\/drop\/ (this can all be seen in the source code provided on GitHub).<\/p><p class=\"text-base leading-normal\">While it&#8217;s true that you can bypass Libdrop by directly connecting to this URL with cURL or similar tools, this is a situation we&#8217;d like to avoid. Our aim is to maximize usability and minimize the risks for users.<\/p><p class=\"text-base leading-normal\">Since we considered user experience, we also explored the idea of automatically accepting files from trusted peers. However, we recognized the potential risk of someone abusing this feature to spam others, and so decided against it.<\/p><p class=\"text-base leading-normal\">To enhance security, we implemented an authorization system based on Meshnet keys. These keys are retrievable via API after successful user authentication. Since NordVPN is consistently aware of peer public keys, we&#8217;re able to use this information to validate connections at the Libdrop communication level. If a user fails the authorization process, the transfer is terminated \u2014 no questions asked from the receiver side.<\/p><p class=\"text-base leading-normal\">To accomplish this, we employ HMAC with SHA-256 and generate a shared key using the Diffie-Hellman algorithm. When initiating a connection, the NordVPN app provides the public key of the peer. Combined with the private key we already possess from the time of initializing Libdrop, we&#8217;re able to calculate this shared key. Both sides of the transaction do the same, and the process is only deemed successful if the keys match.<\/p><p class=\"text-base leading-normal\">We&#8217;re aware that this system isn&#8217;t bulletproof. For instance, users might find a way to exploit a Linux CLI app. However, we believe these improvements represent a significant step towards creating a safer and more reliable experience for our users.<\/p><h2 id=\"Permissions and user access\" class=\"text-h2 leading-none text-left\"><b>Permissions and user access<\/b><\/h2><p class=\"text-base leading-normal\">Integrated into the NordVPN application, Libdrop operates under the constraints of user permissions as enforced by the operating system. This ensures that users can only share files to which they have ownership rights. To initiate a file transfer, a connection between peers must first be established. Enabling file sharing for a specific Meshnet peer allows one to start receiving files from that device. Disabling file-sharing permissions for a Meshnet peer will halt incoming transfers from that particular device. <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/meshnet.nordvpn.com\/features\/explaining-permissions\/file-sharing-permissions\" target=\"_blank\" rel=\"noopener noreferrer\">You can read more about file-sharing permissions here.<\/a><\/p><p class=\"text-base leading-normal\">On the Linux platform, we faced an additional challenge because the app needed to run as root due to Libtelio&#8217;s requirements. Running Libdrop as root was out of the question, as it would have unrestricted access to the entire file system. To navigate this, we set Libdrop up to run as a user process that communicates with the NordVPN daemon.<\/p><p class=\"text-base leading-normal\">Fortunately, mobile devices didn&#8217;t present the same issue, thanks to their robust sandboxing. Likewise, applications on Windows and MacOS operate with user permissions, so there were no concerns on those platforms either.<\/p><p class=\"text-base leading-normal\">It&#8217;s worth noting that Libdrop isn&#8217;t designed for multi-user scenarios, as it uses a hardcoded port number, 49111. However, it can technically bind to different network interfaces without any problems.<\/p><h2 id=\"File aggregation\" class=\"text-h2 leading-none text-left\"><b>File aggregation<\/b><\/h2><p class=\"text-base leading-normal\">To simplify the user experience and streamline integration, we designed Libdrop to automatically enumerate files in the paths provided. These paths can point to either individual files or directories, allowing for greater flexibility. This setup posed several challenges, however:<\/p><ul class=\"list-disc ml-24\"><li class=\"ml-20\"><div><p class=\"text-base leading-normal\">How can we recreate the directory hierarchy?<\/p><\/div><\/li><li class=\"ml-20\"><div><p class=\"text-base leading-normal\">What do we do when we encounter a symlink?<\/p><\/div><\/li><li class=\"ml-20\"><div><p class=\"text-base leading-normal\">What happens if there are too many files?<\/p><\/div><\/li><li class=\"ml-20\"><div><p class=\"text-base leading-normal\">What are the issues with Android permissions?<\/p><\/div><\/li><\/ul><p class=\"text-base leading-normal\">Let\u2019s take a closer look at how we overcame these challenges.<\/p><h2 id=\"Recreating the directory hierarchy\" class=\"text-h2 leading-none text-left\"><b>Recreating the directory hierarchy<\/b><\/h2><p class=\"text-base leading-normal\">For hierarchies, we used the same rename logic as we did with the files, but only for the root level directory. We only communicate the path with the peer starting at the root level of the provided path, meaning that if there\u2019s a directory structure of C:\\Files\\Photos\\Cats\\Cute and the user adds C:\\File\\Photos then we only send Photos\\*, the receiver is unaware of the C:\\Files portion. This was important because, if the receiver was aware of that portion, personal details could be leaked.<\/p><p class=\"text-base leading-normal\">Interestingly, directory separators are not cross-platform. Windows supports both \\ and \/ while Unix-based OSs (Android, iOS, MacOS, Linux) support only \/. Initially, we just communicated with the path as-is, which then produced some fun results. Sending a path, \u201cPhotos\\Cats\\1.jpg,\u201d from Windows to a Linux machine would produce a file with that name instead of two directories and one file when transferring a directory.<\/p><p class=\"text-base leading-normal\">As an easy solution, we chose the following approach: when the user sends a directory and we aggregate a path, we split it with the native path separator and then glue it back together using the universal one \u2014 \/. We can then use that path going forward.<\/p><h2 id=\"Dealing with symlinks\" class=\"text-h2 leading-none text-left\"><b>Dealing with symlinks<\/b><\/h2><p class=\"text-base leading-normal\">We decided that, when a symlink is encountered, we would return an error. This reduces the chances of possible security issues arising around certain files.<\/p><p class=\"text-base leading-normal\">Symlinks reduce the visibility of operations, creating situations in which a user might think they are sending one set of files while in reality a different group of files are picked up.<\/p><h2 id=\"What happens if there are too many files?\" class=\"text-h2 leading-none text-left\"><b>What happens if there are too many files?<\/b><\/h2><p class=\"text-base leading-normal\">In Libdrop we allow for certain configuration values when initializing the library, ensuring that it can be flexible across multiple platforms. To help with interoperability, we decided to add two values: file limit and file depth limit.<\/p><p class=\"text-base leading-normal\">Including these two values means that deep directories result in an error. An error is also generated when the file limit is reached. We think it\u2019s better to be explicit than implicit, and so we\u2019d rather generate an error than send an incomplete file transfer.<\/p><h2 id=\"Android permission issue\" class=\"text-h2 leading-none text-left\"><b>Android permission issue<\/b><\/h2><p class=\"text-base leading-normal\">Using the transfer system on Android presented us with some challenges. In order to use the POSIX file system, the API needs appropriate permissions in the application manifest. Direct file system access requires that the application is placed within a single specific category, but this was a problem because NordVPN is not just a file or backup manager.<\/p><p class=\"text-base leading-normal\">A solution was found when we did an experiment and found that upon selecting the file in Android, it was possible to <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/developer.android.com\/reference\/android\/os\/ParcelFileDescriptor#detachFd()\" target=\"_blank\" rel=\"noopener noreferrer\">detach the file descriptor<\/a>. This enabled us to use POSIX with the provided descriptor:<\/p><h2 id=\"Testing and dogfooding\" class=\"text-h2 leading-none text-left\"><b>Testing and dogfooding<\/b><\/h2><p class=\"text-base leading-normal\">We used Python and Docker to load the compiled library and imitate conversation between two peers. This allowed us to reproduce the bugs by writing test cases, easing our concerns about bigger changes in the codebase.<\/p><p class=\"text-base leading-normal\">The testing framework allowed us to generate scenarios quickly using a Python API where we can imitate all the actions a user might take alongside the events we would expect as a result.<\/p><p class=\"text-base leading-normal\">Tests can\u2019t perfectly replicate what happens in real life so we still constantly seek QA feedback alongside the relevant aggregated logs. Still, having an easy-to-use test framework proved to be very beneficial and boosted our confidence during development.<\/p><h2 id=\"Meshnet protocol and wire safety\" class=\"text-h2 leading-none text-left\"><b>Meshnet protocol and wire safety<\/b><\/h2><p class=\"text-base leading-normal\">NordVPN&#8217;s file-sharing feature is built on Meshnet, a peer-to-peer protocol. This design allows for the shortest possible data path between computers, eliminating the need for third-party cloud storage or service providers.<\/p><p class=\"text-base leading-normal\">One caveat is that both Meshnet nodes must be online simultaneously for the transfer to take place. All traffic between Meshnet nodes, including file sharing, is authenticated and encrypted via WireGuard\u2019s cryptography, ensuring that even Nord Security cannot access the contents of the files or the traffic being transmitted. You can <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.wireguard.com\/protocol\/\" target=\"_blank\" rel=\"noopener noreferrer\">read more about the Wireguard protocol here<\/a>.<\/p><p class=\"text-base leading-normal\">Thanks to Libtelio and Meshnet, Libdrop doesn\u2019t need to use any encryption of its own because double-encryption would be unnecessary. If you\u2019re considering implementing Libdrop into your own product, you should integrate transport layer security (TLS), which should be fairly trivial to implement.<\/p><p class=\"text-base leading-normal\">In summary, NordVPN&#8217;s File Sharing feature offers a secure, efficient, user and API-user-friendly method for peer-to-peer file transfers through the Meshnet.<\/p><\/div><\/div><\/div>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-cf03edf elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"cf03edf\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-b576c6d\" data-id=\"b576c6d\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-bfd91ca elementor-widget elementor-widget-shortcode\" data-id=\"bfd91ca\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\t\t<div data-elementor-type=\"page\" data-elementor-id=\"18103\" class=\"elementor elementor-18103\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-748947f elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"748947f\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;_id&quot;:&quot;c4f773e&quot;,&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-7995c19\" data-id=\"7995c19\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-a437045 elementor-widget elementor-widget-image-box\" data-id=\"a437045\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image-box.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"elementor-image-box-wrapper\"><div class=\"elementor-image-box-content\"><h3 class=\"elementor-image-box-title\">About Version 2 Digital<\/h3><p class=\"elementor-image-box-description\">Version 2 Digital is one of the most dynamic IT companies in Asia. The company distributes a wide range of IT products across various areas including cyber security, cloud, data protection, end points, infrastructures, system monitoring, storage, networking, business productivity and communication products.\n<br><br>\nThrough an extensive network of channels, point of sales, resellers, and partnership companies, Version 2 offers quality products and services which are highly acclaimed in the market. Its customers cover a wide spectrum which include Global 1000 enterprises, regional listed companies, different vertical industries, public utilities, Government, a vast number of successful SMEs, and consumers in various Asian cities.<\/p><\/div><\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t\n\t\t<div data-elementor-type=\"page\" data-elementor-id=\"63561\" class=\"elementor elementor-63561\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-1b6aa2c4 elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"1b6aa2c4\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;_id&quot;:&quot;c4f773e&quot;,&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-1b283ee5\" data-id=\"1b283ee5\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-4e466f1a elementor-widget elementor-widget-text-editor\" data-id=\"4e466f1a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><strong>About NordLayer<br \/><\/strong>NordLayer is an adaptive network access security solution for modern businesses \u2013 from the world\u2019s most trusted cybersecurity brand, Nord Security.<\/p><p>The web has become a chaotic space where safety and trust have been compromised by cybercrime and data protection issues. Therefore, our team has a global mission to shape a more trusted and peaceful online future for people everywhere.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-9e34e91 elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"9e34e91\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;_id&quot;:&quot;c4f773e&quot;,&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-bb2c932\" data-id=\"bb2c932\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-c6a493c elementor-widget elementor-widget-text-editor\" data-id=\"c6a493c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><strong>About NordLayer<br \/><\/strong>NordLayer is an adaptive network access security solution for modern businesses \u2013 from the world\u2019s most trusted cybersecurity brand, Nord Security.<\/p><p>The web has become a chaotic space where safety and trust have been compromised by cybercrime and data protection issues. Therefore, our team has a global mission to shape a more trusted and peaceful online future for people everywhere.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>\u00a0 The Libdrop library allows NordVPN users to share fil [&hellip;]<\/p>\n","protected":false},"author":149011790,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":true},"categories":[973,1130,1273,61],"tags":[974,1132,1272],"class_list":["post-75553","post","type-post","status-publish","format-standard","hentry","category-nord-security","category-nordlayer","category-1273","category-press-release","tag-nord-security","tag-nordlayer","tag-1272"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Libdrop: File sharing through NordVPN - Version 2<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn\" \/>\n<meta property=\"og:locale\" content=\"zh_HK\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Libdrop: File sharing through NordVPN - Version 2\" \/>\n<meta property=\"og:description\" content=\"\u00a0 The Libdrop library allows NordVPN users to share fil [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn\" \/>\n<meta property=\"og:site_name\" content=\"Version 2\" \/>\n<meta property=\"article:published_time\" content=\"2024-02-20T09:25:54+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2024\/02\/featured-image.png\" \/>\n<meta name=\"author\" content=\"tracylamv2\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"tracylamv2\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9810\u8a08\u95b1\u8b80\u6642\u9593\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 \u5206\u9418\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/libdrop-file-sharing-through-nordvpn#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/2024\\\/02\\\/libdrop-file-sharing-through-nordvpn\\\/\"},\"author\":{\"name\":\"tracylamv2\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/person\\\/011bc7c3731c930bcfeecd52fefb6365\"},\"headline\":\"Libdrop: File sharing through NordVPN\",\"datePublished\":\"2024-02-20T09:25:54+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/2024\\\/02\\\/libdrop-file-sharing-through-nordvpn\\\/\"},\"wordCount\":2985,\"publisher\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/libdrop-file-sharing-through-nordvpn#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/res.cloudinary.com\\\/nordsec\\\/f_auto,c_limit,w_1200,q_auto\\\/v1\\\/nord-security-web\\\/blog\\\/categories\\\/engineering\\\/2024\\\/02\\\/featured-image.png\",\"keywords\":[\"Nord Security\",\"NordLayer\",\"2024\"],\"articleSection\":[\"Nord Security\",\"NordLayer\",\"2024\",\"Press Release\"],\"inLanguage\":\"zh-HK\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/version-2.com\\\/2024\\\/02\\\/libdrop-file-sharing-through-nordvpn\\\/\",\"url\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/libdrop-file-sharing-through-nordvpn\",\"name\":\"Libdrop: File sharing through NordVPN - Version 2\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/libdrop-file-sharing-through-nordvpn#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/libdrop-file-sharing-through-nordvpn#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/res.cloudinary.com\\\/nordsec\\\/f_auto,c_limit,w_1200,q_auto\\\/v1\\\/nord-security-web\\\/blog\\\/categories\\\/engineering\\\/2024\\\/02\\\/featured-image.png\",\"datePublished\":\"2024-02-20T09:25:54+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/libdrop-file-sharing-through-nordvpn#breadcrumb\"},\"inLanguage\":\"zh-HK\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/libdrop-file-sharing-through-nordvpn\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/libdrop-file-sharing-through-nordvpn#primaryimage\",\"url\":\"https:\\\/\\\/res.cloudinary.com\\\/nordsec\\\/f_auto,c_limit,w_1200,q_auto\\\/v1\\\/nord-security-web\\\/blog\\\/categories\\\/engineering\\\/2024\\\/02\\\/featured-image.png\",\"contentUrl\":\"https:\\\/\\\/res.cloudinary.com\\\/nordsec\\\/f_auto,c_limit,w_1200,q_auto\\\/v1\\\/nord-security-web\\\/blog\\\/categories\\\/engineering\\\/2024\\\/02\\\/featured-image.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/libdrop-file-sharing-through-nordvpn#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9801\",\"item\":\"https:\\\/\\\/version-2.com\\\/zh\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Libdrop: File sharing through NordVPN\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#website\",\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/\",\"name\":\"Version 2\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/version-2.com\\\/zh\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"zh-HK\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\",\"name\":\"Version 2\",\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/version-2.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/version-2.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1\",\"width\":1795,\"height\":335,\"caption\":\"Version 2\"},\"image\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/person\\\/011bc7c3731c930bcfeecd52fefb6365\",\"name\":\"tracylamv2\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9d01d79cbfd8b2e878f5d701a362cc9fca466d33fec977b59706c23c1a2db15c?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9d01d79cbfd8b2e878f5d701a362cc9fca466d33fec977b59706c23c1a2db15c?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9d01d79cbfd8b2e878f5d701a362cc9fca466d33fec977b59706c23c1a2db15c?s=96&d=identicon&r=g\",\"caption\":\"tracylamv2\"},\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/author\\\/tracylamv2\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Libdrop: File sharing through NordVPN - Version 2","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn","og_locale":"zh_HK","og_type":"article","og_title":"Libdrop: File sharing through NordVPN - Version 2","og_description":"\u00a0 The Libdrop library allows NordVPN users to share fil [&hellip;]","og_url":"https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn","og_site_name":"Version 2","article_published_time":"2024-02-20T09:25:54+00:00","og_image":[{"url":"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2024\/02\/featured-image.png","type":"","width":"","height":""}],"author":"tracylamv2","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"tracylamv2","\u9810\u8a08\u95b1\u8b80\u6642\u9593":"15 \u5206\u9418"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn#article","isPartOf":{"@id":"https:\/\/version-2.com\/2024\/02\/libdrop-file-sharing-through-nordvpn\/"},"author":{"name":"tracylamv2","@id":"https:\/\/version-2.com\/zh\/#\/schema\/person\/011bc7c3731c930bcfeecd52fefb6365"},"headline":"Libdrop: File sharing through NordVPN","datePublished":"2024-02-20T09:25:54+00:00","mainEntityOfPage":{"@id":"https:\/\/version-2.com\/2024\/02\/libdrop-file-sharing-through-nordvpn\/"},"wordCount":2985,"publisher":{"@id":"https:\/\/version-2.com\/zh\/#organization"},"image":{"@id":"https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2024\/02\/featured-image.png","keywords":["Nord Security","NordLayer","2024"],"articleSection":["Nord Security","NordLayer","2024","Press Release"],"inLanguage":"zh-HK"},{"@type":"WebPage","@id":"https:\/\/version-2.com\/2024\/02\/libdrop-file-sharing-through-nordvpn\/","url":"https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn","name":"Libdrop: File sharing through NordVPN - Version 2","isPartOf":{"@id":"https:\/\/version-2.com\/zh\/#website"},"primaryImageOfPage":{"@id":"https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn#primaryimage"},"image":{"@id":"https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2024\/02\/featured-image.png","datePublished":"2024-02-20T09:25:54+00:00","breadcrumb":{"@id":"https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn#breadcrumb"},"inLanguage":"zh-HK","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn"]}]},{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn#primaryimage","url":"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2024\/02\/featured-image.png","contentUrl":"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2024\/02\/featured-image.png"},{"@type":"BreadcrumbList","@id":"https:\/\/nordsecurity.com\/blog\/libdrop-file-sharing-through-nordvpn#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9801","item":"https:\/\/version-2.com\/zh\/"},{"@type":"ListItem","position":2,"name":"Libdrop: File sharing through NordVPN"}]},{"@type":"WebSite","@id":"https:\/\/version-2.com\/zh\/#website","url":"https:\/\/version-2.com\/zh\/","name":"Version 2","description":"","publisher":{"@id":"https:\/\/version-2.com\/zh\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/version-2.com\/zh\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"zh-HK"},{"@type":"Organization","@id":"https:\/\/version-2.com\/zh\/#organization","name":"Version 2","url":"https:\/\/version-2.com\/zh\/","logo":{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/version-2.com\/zh\/#\/schema\/logo\/image\/","url":"https:\/\/i0.wp.com\/version-2.com\/wp-content\/uploads\/2020\/08\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1","contentUrl":"https:\/\/i0.wp.com\/version-2.com\/wp-content\/uploads\/2020\/08\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1","width":1795,"height":335,"caption":"Version 2"},"image":{"@id":"https:\/\/version-2.com\/zh\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/version-2.com\/zh\/#\/schema\/person\/011bc7c3731c930bcfeecd52fefb6365","name":"tracylamv2","image":{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/secure.gravatar.com\/avatar\/9d01d79cbfd8b2e878f5d701a362cc9fca466d33fec977b59706c23c1a2db15c?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/9d01d79cbfd8b2e878f5d701a362cc9fca466d33fec977b59706c23c1a2db15c?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9d01d79cbfd8b2e878f5d701a362cc9fca466d33fec977b59706c23c1a2db15c?s=96&d=identicon&r=g","caption":"tracylamv2"},"url":"https:\/\/version-2.com\/zh\/author\/tracylamv2\/"}]}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pbQRKm-jEB","post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/75553","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/users\/149011790"}],"replies":[{"embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/comments?post=75553"}],"version-history":[{"count":4,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/75553\/revisions"}],"predecessor-version":[{"id":75564,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/75553\/revisions\/75564"}],"wp:attachment":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/media?parent=75553"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/categories?post=75553"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/tags?post=75553"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}