How can I block an abusive person who endlessly tries to register more accounts? I have a free site with open registration; anyone can register and I am not able to change that.  However, accounts must be approved by an administrator after completing a profile, so I have access to a variety of info to identify duplicate users (date of birth, "self introduction" comment, email address, photos, reported location in profile, geolocated IP, IP address, etc.)

Recently the site has become subject to the attacks of a single user who is extremely abusive and seems to have unlimited time to register multiple accounts.  These accounts can be blocked relatively easily, but it's a lot of work for the administrator (me) and I'm afraid I will miss one among the legitimate accounts (this user registers about 6 accounts per day).

I have already:


banned the user's known IP addresses
blocked registration from known domains that are used for "disposable" email addresses
added a special view to help me identify accounts based on known patterns of access from the user


Is there anything I can do with cookies, etc. to make it even more difficult for this user to register?

This is a Drupal 7 site.

EDIT: In my case, this is a human user, not a bot.  But the bot answers are useful for those who are being specifically targeted by spammers.
Instead of trying to prevent the user from registering, which is a game for trolls and hackers alike, make the site annoying for him. Make him want to leave, as opposed to making him want to win the trolling game.

What I've done in the past, not specific to Drupal, is to let the user register. I then sabotaged his specific account:


I sprinkled if ($someuser) { sleep(rand($base, $base*2)) } in the code, where $base would increase daily. I made sure that he had lots of timeouts.
I would drop N% of his posts, where N started above 50% and only increased from there. If the post had certain keywords, it would be dropped immediately.
I would randomly drop CSS rules so the page would display poorly. Again, the severity would increase in time.


This required more effort on my part, but as per Sun Tzu's advice I was conditioning the user to hate my site. I wanted him to feel not that he was annoying us, but rather that he should be annoyed by the delays and apparent bugs. It took less than a week for him to give up on us.

EDIT: In the comments, user rooby mentions the Misery module which is based on the same concept:


Delay: Create a random-length delay, giving the appearance of a slow connection. (by default this happens 40% of the time)
White screen: Present the user with a white-screen. (by default this happens 10% of the time)
Wrong page: Redirect to a random URL in a predefined list. (by default this happens 0% of the time)
Random node: Redirect to a random node accessible by the user. (by default this happens 10% of the time)
403 Access Denied: Present the user with an "Access Denied" error. (by default this happens 10% of the time)
404 Not Found: Present the user with a "Not Found" error. (by default this happens 10% of the time)
Forms don't submit: Redirect back to the form during validation to prevent submission. (by default this happens 60% of the time) Note: Occasionally certain forms validate based on which button was pressed, this won't work in those cases.
Crash IE6: If the user is using Internet Explorer 6, this will crash their browser. (by default this happens 0% of the time)
Spam: Replace node content with a set word. (by default this happens 10% of the time)
Logout: Log the user out. (by default this happens 10% of the time)