diff --git a/include/nbd_proxy.hpp b/include/nbd_proxy.hpp
new file mode 100644
index 0000000..64578f2
--- /dev/null
+++ b/include/nbd_proxy.hpp
@@ -0,0 +1,381 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#pragma once
+#include <app.h>
+#include <websocket.h>
+
+#include <boost/asio.hpp>
+#include <boost/beast/core/buffers_to_string.hpp>
+#include <boost/beast/core/multi_buffer.hpp>
+#include <boost/container/flat_map.hpp>
+#include <dbus_utility.hpp>
+#include <experimental/filesystem>
+#include <variant>
+#include <webserver_common.hpp>
+
+namespace crow
+{
+
+namespace nbd_proxy
+{
+
+using boost::asio::local::stream_protocol;
+
+static constexpr auto nbdBufferSize = 131088;
+
+struct NbdProxyServer : std::enable_shared_from_this<NbdProxyServer>
+{
+    NbdProxyServer(crow::websocket::Connection& connIn,
+                   const std::string& socketIdIn,
+                   const std::string& endpointIdIn, const std::string& pathIn) :
+        socketId(socketIdIn),
+        endpointId(endpointIdIn), path(pathIn),
+        acceptor(connIn.get_io_context(), stream_protocol::endpoint(socketId)),
+        connection(connIn)
+    {
+    }
+
+    ~NbdProxyServer()
+    {
+        BMCWEB_LOG_DEBUG << "NbdProxyServer destructor";
+        close();
+        connection.close();
+
+        if (peerSocket)
+        {
+            BMCWEB_LOG_DEBUG << "peerSocket->close()";
+            peerSocket->close();
+            peerSocket.reset();
+            BMCWEB_LOG_DEBUG << "std::remove(" << socketId << ")";
+            std::remove(socketId.c_str());
+        }
+    }
+
+    std::string getEndpointId() const
+    {
+        return endpointId;
+    }
+
+    void run()
+    {
+        acceptor.async_accept(
+            [this, self(shared_from_this())](boost::system::error_code ec,
+                                             stream_protocol::socket socket) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Cannot accept new connection: " << ec;
+                    return;
+                }
+                if (peerSocket)
+                {
+                    // Something is wrong - socket shouldn't be acquired at this
+                    // point
+                    BMCWEB_LOG_ERROR
+                        << "Failed to open connection - socket already used";
+                    return;
+                }
+
+                BMCWEB_LOG_DEBUG << "Connection opened";
+                peerSocket = std::move(socket);
+                doRead();
+
+                // Trigger Write if any data was sent from server
+                // Initially this is negotiation chunk
+                doWrite();
+            });
+
+        auto mountHandler = [](const boost::system::error_code ec,
+                               const bool status) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << "DBus error: " << ec
+                                 << ", cannot call mount method";
+                return;
+            }
+        };
+
+        crow::connections::systemBus->async_method_call(
+            std::move(mountHandler), "xyz.openbmc_project.VirtualMedia", path,
+            "xyz.openbmc_project.VirtualMedia.Proxy", "Mount");
+    }
+
+    void send(const std::string_view data)
+    {
+        boost::asio::buffer_copy(ws2uxBuf.prepare(data.size()),
+                                 boost::asio::buffer(data));
+        ws2uxBuf.commit(data.size());
+        doWrite();
+    }
+
+    void close()
+    {
+        // The reference to session should exists until unmount is
+        // called
+        auto unmountHandler = [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << "DBus error: " << ec
+                                 << ", cannot call unmount method";
+                return;
+            }
+        };
+
+        crow::connections::systemBus->async_method_call(
+            std::move(unmountHandler), "xyz.openbmc_project.VirtualMedia", path,
+            "xyz.openbmc_project.VirtualMedia.Proxy", "Unmount");
+    }
+
+  private:
+    void doRead()
+    {
+        if (!peerSocket)
+        {
+            BMCWEB_LOG_DEBUG << "UNIX socket isn't created yet";
+            // Skip if UNIX socket is not created yet.
+            return;
+        }
+
+        // Trigger async read
+        peerSocket->async_read_some(
+            ux2wsBuf.prepare(nbdBufferSize),
+            [this, self(shared_from_this())](boost::system::error_code ec,
+                                             std::size_t bytesRead) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "UNIX socket: async_read_some error = "
+                                     << ec;
+                    // UNIX socket has been closed by peer, best we can do is to
+                    // break all connections
+                    close();
+                    return;
+                }
+
+                // Fetch data from UNIX socket
+
+                ux2wsBuf.commit(bytesRead);
+
+                // Paste it to WebSocket as binary
+                connection.sendBinary(
+                    boost::beast::buffers_to_string(ux2wsBuf.data()));
+                ux2wsBuf.consume(bytesRead);
+
+                // Allow further reads
+                doRead();
+            });
+    }
+
+    void doWrite()
+    {
+        if (!peerSocket)
+        {
+            BMCWEB_LOG_DEBUG << "UNIX socket isn't created yet";
+            // Skip if UNIX socket is not created yet. Collect data, and wait
+            // for nbd-client connection
+            return;
+        }
+
+        if (uxWriteInProgress)
+        {
+            BMCWEB_LOG_ERROR << "Write in progress";
+            return;
+        }
+
+        if (ws2uxBuf.size() == 0)
+        {
+            BMCWEB_LOG_ERROR << "No data to write to UNIX socket";
+            return;
+        }
+
+        uxWriteInProgress = true;
+        boost::asio::async_write(
+            *peerSocket, ws2uxBuf.data(),
+            [this, self(shared_from_this())](boost::system::error_code ec,
+                                             std::size_t bytesWritten) {
+                ws2uxBuf.consume(bytesWritten);
+                uxWriteInProgress = false;
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "UNIX: async_write error = " << ec;
+                    return;
+                }
+                // Retrigger doWrite if there is something in buffer
+                doWrite();
+            });
+    }
+
+    // Keeps UNIX socket endpoint file path
+    const std::string socketId;
+    const std::string endpointId;
+    const std::string path;
+
+    bool uxWriteInProgress = false;
+
+    // UNIX => WebSocket buffer
+    boost::beast::multi_buffer ux2wsBuf;
+
+    // WebSocket <= UNIX buffer
+    boost::beast::multi_buffer ws2uxBuf;
+
+    // Default acceptor for UNIX socket
+    stream_protocol::acceptor acceptor;
+
+    // The socket used to communicate with the client.
+    std::optional<stream_protocol::socket> peerSocket;
+
+    crow::websocket::Connection& connection;
+};
+
+static boost::container::flat_map<crow::websocket::Connection*,
+                                  std::shared_ptr<NbdProxyServer>>
+    sessions;
+
+void requestRoutes(CrowApp& app)
+{
+    BMCWEB_ROUTE(app, "/nbd/<str>")
+        .websocket()
+        .onopen([&app](crow::websocket::Connection& conn,
+                       std::shared_ptr<bmcweb::AsyncResp> asyncResp) {
+            BMCWEB_LOG_DEBUG << "nbd-proxy.onopen(" << &conn << ")";
+
+            for (const auto session : sessions)
+            {
+                if (session.second->getEndpointId() == conn.req.target())
+                {
+                    BMCWEB_LOG_ERROR
+                        << "Cannot open new connection - socket is in use";
+                    return;
+                }
+            }
+
+            auto openHandler = [asyncResp, &conn](
+                                   const boost::system::error_code ec,
+                                   dbus::utility::ManagedObjectType& objects) {
+                const std::string* socketValue = nullptr;
+                const std::string* endpointValue = nullptr;
+                const std::string* endpointObjectPath = nullptr;
+
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "DBus error: " << ec;
+                    return;
+                }
+
+                for (const auto& objectPath : objects)
+                {
+                    const auto interfaceMap = objectPath.second.find(
+                        "xyz.openbmc_project.VirtualMedia.MountPoint");
+
+                    if (interfaceMap == objectPath.second.end())
+                    {
+                        BMCWEB_LOG_DEBUG << "Cannot find MountPoint object";
+                        continue;
+                    }
+
+                    const auto endpoint =
+                        interfaceMap->second.find("EndpointId");
+                    if (endpoint == interfaceMap->second.end())
+                    {
+                        BMCWEB_LOG_DEBUG << "Cannot find EndpointId property";
+                        continue;
+                    }
+
+                    endpointValue = std::get_if<std::string>(&endpoint->second);
+
+                    if (endpointValue == nullptr)
+                    {
+                        BMCWEB_LOG_ERROR << "EndpointId property value is null";
+                        continue;
+                    }
+
+                    if (*endpointValue == conn.req.target())
+                    {
+                        const auto socket = interfaceMap->second.find("Socket");
+                        if (socket == interfaceMap->second.end())
+                        {
+                            BMCWEB_LOG_DEBUG << "Cannot find Socket property";
+                            continue;
+                        }
+
+                        socketValue = std::get_if<std::string>(&socket->second);
+                        if (socketValue == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR << "Socket property value is null";
+                            continue;
+                        }
+
+                        endpointObjectPath = &objectPath.first.str;
+                        break;
+                    }
+                }
+
+                if (endpointObjectPath == nullptr)
+                {
+                    BMCWEB_LOG_ERROR << "Cannot find requested EndpointId";
+                    asyncResp->res.result(
+                        boost::beast::http::status::not_found);
+                    return;
+                }
+
+                // If the socket file exists (i.e. after bmcweb crash), we
+                // cannot reuse it.
+                std::remove((*socketValue).c_str());
+
+                sessions[&conn] = std::make_shared<NbdProxyServer>(
+                    conn, std::move(*socketValue), std::move(*endpointValue),
+                    std::move(*endpointObjectPath));
+
+                sessions[&conn]->run();
+
+                asyncResp->res.result(boost::beast::http::status::ok);
+            };
+            crow::connections::systemBus->async_method_call(
+                std::move(openHandler), "xyz.openbmc_project.VirtualMedia",
+                "/xyz/openbmc_project/VirtualMedia",
+                "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+        })
+        .onclose(
+            [](crow::websocket::Connection& conn, const std::string& reason) {
+                BMCWEB_LOG_DEBUG << "nbd-proxy.onclose(reason = '" << reason
+                                 << "')";
+                auto session = sessions.find(&conn);
+                if (session == sessions.end())
+                {
+                    BMCWEB_LOG_DEBUG << "No session to close";
+                    return;
+                }
+                // Remove reference to session in global map
+                session->second->close();
+                sessions.erase(session);
+            })
+        .onmessage([](crow::websocket::Connection& conn,
+                      const std::string& data, bool isBinary) {
+            BMCWEB_LOG_DEBUG << "nbd-proxy.onmessage(len = " << data.length()
+                             << ")";
+            // Acquire proxy from sessions
+            auto session = sessions.find(&conn);
+            if (session != sessions.end())
+            {
+                if (session->second)
+                {
+                    session->second->send(data);
+                    return;
+                }
+            }
+            conn.close();
+        });
+}
+} // namespace nbd_proxy
+} // namespace crow
