My bitcoin faucet has been running since 2013, and running it has been uneventful most of the time. Only a few developers and users wanted to experiment with bitcoin and saw a need for testnet coins. I ran a few experiments myself with the faucet, the most interesting one was to run a joinmarket node to send out the coins with a CoinJoin transaction.
In late 2017/early 2018 when bitcoin reached its all time high value (as of today) requests for my faucet increased. I had automated all the payouts: requests came in during the day and would automatically be processed at night.
What I had not considered: testnet coins had become valuable to some people. What many aspiring bitcoin service developers don't know: there are at least two viable options to get started: regtest and the bitcoin testnet box. If those are not enough to start your experiments, development or testing you should reconsider your architecture.
Code should be unit tested first, this means that you test functions and classes in isolation. This doesn't need any connection to the bitcoin network at all. If you need a connection to a bitcoin node you can use the regtest option. If you think you need to test the integration between two totally separated services you can use the testnet box. You really don't need to interact with the real testnet, that's why you test your interfaces.
Anyway, some people lack that knowledge and think they absolutely need testnet bitcoin, and other people will happily sell it to them, if they can get some. That's where my faucet came into play: somebody automated getting coins from the faucet and drained it in a few weeks. I finally noticed when it was empty and I received error messages by email. Fortunately I know a friendly person who can supply me with more testnet bitcoin, so I was able to restart the faucet quickly but I began to add protective measures.
Detecting malicious users
I will not go into too much detail here, even though I'm sure most of the malicious users are not very sophisticated when it comes to technology. The first counter-measure was very easy to implement, some spammers simply made dozens of requests from the same IP address. Blocking repeated IP addresses eliminated around half of all requests which was very nice and gave me the confidence to automate the payments again, with some sanity checks and a captcha in place to prevent big spikes.
But now the spammers had piqued my interest and only blocking the most obvious ones didn't feel good enough. I started to look into usage patterns and quickly figured out another effective countermeasure, I added a session ID to the browser. Some of the spammers were obviously more sophisticated than others and tried to hide their activity behind a VPN or similar services and this was a good way of detecting them.
The chart below shows the situation when I started to implement the simple automated blocking. On an average day just a few users generated half or more of all faucet requests.
Several breakthroughs happened later when I started to analyze browser fingerprints and geolocation data. I could find connections between this new data and the previously observed usage patterns which revealed clusters of users. At that point I was able combine different data sources and implement a simple "badness" scoring system.
Nowadays the obvious repeated requests are down to around 10%. The chart below is a high level overview of recently observed suspicious characteristics, the actual data shows that suspicious behavior usually originates from a suspicious environment. On an average day a third of all requests are blocked based on a combination of those characteristics.
Drastically reducing fraudulent activity on my testnet faucet wasn't very hard, but it certainly took some time to gather all the data and to interpret it. Most of the fraudulent requests originated from less wealthy regions and were performed manually, which is not surprising I guess. I don't like that I have to make life harder for people living there, but I blame poorly informed developers. Stop spending fiat money for testnet bitcoin.