Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
fbtftp
is Facebook's implementation of a dynamic TFTP server framework. It
lets you create custom TFTP servers and wrap your own logic into it in a very
simple manner.
Facebook currently uses it in production, and it's deployed at global scale
across all of our data centers.
We love to use existing open source software and to contribute upstream, but sometimes it's just not enough at our scale. We ended up writing our own tftp framework and decided to open source it.
fbtftp
was born from the need of having an easy-to-configure and
easy-to-expand TFTP server, that would work at large scale. The standard
in.tftpd
is a 20+ years old piece of software written in C that is very
difficult to extend.
fbtftp
is written in python3
and lets you plug your own logic to:
fbtftp
at Facebook?We created our own Facebook-specific server based on the framework to:
It depends on your needs! fbtftp
is written in Python 3 using a
multiprocessing model; its primary focus is not speed, but flexibility and
scalability. Yet it is fast enough at our datacenter scale :)
It is well-suited for large installations where scalability and custom features
are needed.
The framework implements the following RFCs:
Note that the server framework only support RRQs (read only) operations. (Who uses WRQ TFTP requests in 2019? :P)
All you need to do is understanding three classes and two callback functions, and you are good to go:
BaseServer
: This class implements the process which deals with accepting new
requests on the UDP port provided. Default TFTP parameters like timeout, port
number and number of retries can be passed. This class doesn't have to be used
directly, you must inherit from it and override get_handler()
method to
return an instance of BaseHandler
.
The class accepts a server_stats_callback
, more about it below. the callback
is not re-entrant, if you need this you have to implement your own locking
logic. This callback is executed periodically and you can use it to publish
server level stats to your monitoring infrastructure. A series of predefined
counters are provided. Refer to the class documentation to find out more.
BaseHandler
: This class deals with talking to a single client. This class
lives into its separate process, process which is spawned by the BaserServer
class, which will make sure to reap the child properly when the session is
over. Do not use this class as is, instead inherit from it and override the get_response_data()
method. Such method must return an instance of a subclass of ResponseData
.
ResponseData
: it's a file-like class that implements read(num_bytes)
,
size()
and close()
. As the previous two classes you'll have to inherit
from this and implement those methods. This class basically let you define how
to return the actual data
server_stats_callback
: function that is called periodically (every 60
seconds by default). The callback is not re-entrant, if you need this you have
to implement your own locking logic. This callback is executed periodically
and you can use it to publish server level stats to your monitoring
infrastructure. A series of predefined counters are provided.
Refer to the class documentation to find out more.
session_stats_callback
: function that is called when a client session is
over.
fbtftp
is distributed with the standard distutils
package, so you can build
it with:
python setup.py build
and install it with:
python setup.py install
Be sure to run as root if you want to install fbtftp
system wide. You can also
use a virtualenv
, or install it as user by running:
python setup.py install --user
Writing your own server is simple. Let's take a look at how to write a simple server that serves files from disk:
from fbtftp.base_handler import BaseHandler
from fbtftp.base_handler import ResponseData
from fbtftp.base_server import BaseServer
import os
class FileResponseData(ResponseData):
def __init__(self, path):
self._size = os.stat(path).st_size
self._reader = open(path, 'rb')
def read(self, n):
return self._reader.read(n)
def size(self):
return self._size
def close(self):
self._reader.close()
def print_session_stats(stats):
print(stats)
def print_server_stats(stats):
counters = stats.get_and_reset_all_counters()
print('Server stats - every {} seconds'.format(stats.interval))
print(counters)
class StaticHandler(BaseHandler):
def __init__(self, server_addr, peer, path, options, root, stats_callback):
self._root = root
super().__init__(server_addr, peer, path, options, stats_callback)
def get_response_data(self):
return FileResponseData(os.path.join(self._root, self._path))
class StaticServer(BaseServer):
def __init__(self, address, port, retries, timeout, root,
handler_stats_callback, server_stats_callback=None):
self._root = root
self._handler_stats_callback = handler_stats_callback
super().__init__(address, port, retries, timeout, server_stats_callback)
def get_handler(self, server_addr, peer, path, options):
return StaticHandler(
server_addr, peer, path, options, self._root,
self._handler_stats_callback)
def main():
server = StaticServer(address='::', port=69, retries=3, timeout=5,
root='/var/tftproot',
handler_stats_callback=print_session_stats,
server_stats_callback=print_server_stats)
try:
server.run()
except KeyboardInterrupt:
server.close()
if __name__ == '__main__':
main()
fbtftp
was created by Marcin Wyszynski (@marcinwyszynski) and Angelo Failla pallotron@fb.com at Facebook Ireland.
Other honorable contributors:
MIT License
FAQs
A python3 framework to build dynamic TFTP servers
We found that fbtftp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.