GORD (c) 1997, 1998 Gerben Wierda GORD is a hack, not a decently written piece of software! It has been developed as 'example of concept' only. It is my production system, though and has been for a year now. I live dangerously.... ;-) CONTENTS WHAT TO DO WITH THIS FILE WARNING AND DISCLAIMER WHAT DO I NEED TO RUN GORD? HOW GORD WORKS HOW DOES GORD HANDLE GORD? HOW FAST IS GORD? HOW SAFE IS GORD? INSTALLING GORD HOW GORD SHOULD BE USEDD ALTERNATIVE INSTALLATIONS RUNNING THE GORD SERVER WHAT YOU HAVE TO DO ACTIVATE GORD FOR YOU AS A USER USING GORD IN TEST MODE ADDING PEOPLE TO THE ACCEPT DATABASE FILTERING THE REGULAR EXPRESSIONS THE ACTIONS BOUNCES THAT DO NOT INCLUDE THE HEADER USING A RECIPE THAT ACCEPTS ALL MAIL REALLY ADDRESSED TO YOU WHAT TO DO WHEN YOU WANT TO SUBSCRIBE TO A MAILING LIST SOME WAYS IN WHICH SPAMMERS COULD ATTACK THE WORST ATTACK OF ALL EXAMPLE FILTER SETUPS WITH COMMENTS: SENDING CONFIRMATIONS TO ACCEPTED USERS RETURNING RECEIPTS FOR RECEIVED MESSAGES CLOSING REMARKS (KNOWN BUGS ETC) SYSV IPC LIMITATIONS MY ADDRESS WHAT TO DO WITH THIS FILE It is not called README for nothing. Read it at least once. WARNING AND DISCLAIMER GORD is experimental, there are no pretty interfaces for users. But any smart ISP could develop one for his clients and use GORD as a basis to offer this anti-spam service. For me, it just works. I don't see any spam anymore. GORD is experimental, there is not enough decent documentation, so I expect you to be fluent in perl.... If it works fine, we should one day rewrite it cleanly. This software has been grown for testing of concepts only. It has not been designed properly. It needs a redesign, but it works as is, so for the time being... NB: There is no warranty whatsoever. Use at your own risk. WHAT DO I NEED TO RUN GORD? Complete perl 5.00404 (preferably with System V IPC) and the following non-standard modules: Data::Dumper MLDBM GDBM libinet Mailtools System administrator privileges to install (though alternative installations are possible, see below). If you can compile C-code, you can install a fast client, instead of the perl client which has to be compiled every time it is run. HOW GORD WORKS GORD is a local server program that acts as a local mailer. Basically, anyone mailing you for the first time will be denied (but this draconic measure is only a last resort, most messages will not end up there). GORD sends that sender a message. If that person answers within a time limit set by you, he or she will be added to your accept list. As spammers normally do not have vaild e-mail addresses (as they would be found out) this system works (but: see below for some attacks and possible future changes). The (Resent-)From: header generated by the sender is essential. There are some exceptions on this, and they can be handled with the help of recipes (see below). The basic system works like this: 1. Someone sends you a message 2. GORD filters out messages that you want to handle separately like messages from mailing lists or with other characteristics 3. GORD detects this person is unknown to you 4. GORD sends the original sender a message 5. The original sender replies 6. GORD receives the reply and delivers the original message 7. That same sender sends you another message 8. GORD detects that this sender is acceptable and delivers the message 9. If required, GORD sends a confirmation A spammer cannot misuse this basic system. First: if the spammer uses a valid from or reply-to address, he will be swamped by complaints (which is why spammers use stealth mailing). Second, the spammer cannot use a From address that is acceptable to all people he sends to, and it is impossible to find out who is acceptable for any single user. And the unique id's cannot be forged. GORD silently drops anything that tries to fake id's. And by not passing bodies in messages it generates itself, a spammer cannot use the GORD of one system to pass messages to someone else. Users may tell it what filtering recipes to use (if any) and its core is a default behaviour that is based on a 'deny-unless' strategy based on the sender's address. For mailing lists etc there are the recipes. You can be 'not strict' by using a recipe that accepts your proper email address in the To: header as most spammers do not generate individual addresses, but send one message with one generic header to millions of addresses. See below. GORD uses some special headers and a special header format, which has to be tuned for every system running GORD. These headers contain unique id's generated by GORD and a system identification (best is to use the FQDN). See below. HOW DOES GORD HANDLE GORD? GORD cannot handle incoming GORD requests automatically, as this would break the system. Because in that case, a spammer would use a from address from someone else who has a GORD system running and this GORD would automatically generate a request-reply for the spammer and the spammer's message would be delivered. Therefore, when an outside request arrives, GORD will pass it on to the user directly, but it will suppress the body and replace it with its own, giving instructions for reply. A spammer would not be able to misuse that, because the body is replaced and the subject must contain the GORD request. I have been giving thought to automating this process, but that requires giving all messages sent out by a user giving a special ID and providing time outs for these ID's. It can be done by using some sort of transparent front end for sendmail (or directly integrating sendmail). But this software is only meant to prove the workability of the solution/protocol. If it becomes a success, it would be best to rewrite it completely anyway. HOW FAST IS GORD? Pretty fast, I think. Once the perl source is compiled and running, you are working with a very fast system (fast regex for instance). This is why GORD is a server, you don't have to start it for every message. The only thing started for every message is a very small client (which will probably be an optimized C program) and even could be built into the MTA. The server itself only forks, and that is a pretty fast operation. The client and the server use the IANA assigned port 312, they talk a very simple protocol which for the time has been named VSLMP (Very Simple Local Mailer Protocol). HOW SAFE IS GORD? Pretty safe. First, the perl client will act as local mailer himself if it cannot find a GORD server (which might have crashed or been killed) and you have started it with the --safe flag (perl client only). Besides, the exit value is almost always EX_TEMPFAIL, telling sendmail to keep the message and not generate a delivery failure. Secondly, the recipes and such are executed as the recipient user. So, whatever that user can do (but nothing more) can be done by GORD on his/her behalf. Thirdly, GORD is written in PERL with tainted on. Fourthly: you can limit access to GORD with a hosts file in the library directory. This file contains one entry per line. A file with the entry 'localhost' or '127.0.0.1' (without the quotes) will limit access to clients started locally. Of course, if you allow source routing, somebody could reroute local addresses somewhere else, so you shouldn't allow source routing. INSTALLING GORD GORD should be installed by running the install_prog.pl script in the source dir and answering the questions. This works on my system and produces a valid installation but it has not been guarantueed to go so smoothly on other systems. First, there are some file system HOW GORD SHOULD BE USEED The GORD client should preferably be your local mailer. For alternatives, see below. My sendmail.cf contains as I am writing this Mlocal, P=/usr/local/gord/bin/gordclient, F=lsSDFMhPfn, S=10, R=20, A=gordclient --verbose=2 $u --safe=/bin/mail_-d_USER or Mlocal, P=/usr/local/gord/bin/gordmail, F=lsSDFMhPfn, S=10, R=20, A=gordclient -v -S $u When you use Postfix instead of sendmail from Wietse Venema as mailer, say: mailbox_command = /usr/local/gord/bin/gordmail -v -s $$LOGNAME If I get around to it, I'll write an add-on for Postfix. There needs to be a directory for the system-wide info. Mine is /usr/local/gord/lib. This directory is set in the file gord.ph. Several header files have to be available in Perl 'ph' form. This is system dependent. Then, take the request.txt from the examples subdirectory and copy it to the library directory. Edit it. GORD replaces the strings REQUESTSUBJ, USER, SUBJECT and FROM with appropriate replacements. Make sure the right files are setuid root (run 'make setuid'). If you do not know what this means, you should not be installing GORD. The setuid files handle global settings for the daemon, like, who wants to use GORD and what the global recipes are. The only files that are setuid, are the files that may write and read the recipe database and the active database. This database is owned by root and users may start programs that update their recipes and change their status wrt their use of the system. The setuid programs are now not scripts but wrappers around scripts for people who cannot execute setuid scripts. ALTERNATIVE INSTALLATIONS Though gord will act just like a local mailer when a user has not been entered in its database (so it is safe to use it on a system where only a few users use it) it is possible to run it without changing the sendmail config. There are three ways to run GORD: 1. As above, the GORD client is the local mail program in the sendmail config, the GORD server runs constantly in the background and actually does the work, including normal local mailer delivery for users that are not entered in its database. 2. The GORD server runs constantly in the background, but the sendmail config is not changed. Users who use GORD enter the following in their .forward file: |/usr/local/gord/bin/gordclient with the appropriate flags. This program is a perl program, alternatively, if the C program is installed (preferably): |/usr/local/gord/bin/gordmail again with the approriate flags. 3. If you cannot run the GORD server in the background, you can run it on a per-message basis. In a .forward file, put: |/usr/local/gord/bin/gordclient --test | /usr/local/gord/bin/gord --test --myid=YourFQDN This is very resource intensive, as two perl programs (one big) will have to be compiled for every message. This is also largely untested, so use at your own risk. RUNNING THE GORD SERVER This is what I added to my /etc/rc file, just before sendmail is started: (grep '^Mlocal.*gord' /etc/sendmail/sendmail.cf >/dev/null) && \ (echo -n ' gord (compile & install)'; /usr/local/gord/bin/startgord) >/dev/console 2>&1) This starts the GORD server in the background if in my sendmail config gord is the local mailer. WHAT YOU HAVE TO DO ACTIVATE GORD FOR YOU AS A USER Create a directory '.gord' and '.gord/pending' (without the quotes) in your home directory. Here GORD will keep the databases pertaining to you and here it will read recipes (if any). A script is available in the source dir. Run gord_use with the argument 'active' (without the quotes). The system administrator can run gord_use for other users, and use the --user flag. From the moment on that GORD is activated, the request/accept/kill system will be active for you. You don't need to have any recipes, probably most users will be able to make do with the barebone system. (Still to be double-checked: permissions and ownership) USING GORD IN TEST MODE GORD has a test mode that can be activated on a per-user basis, by running gord_use with the argument 'test' (without the quotes). When in test mode, GORD _almost_ behaves as in 'active' mode, except that actions are not taken but added to the header of the message. At the end of processing, the message will be delivered in the standard mailbox. It is not possible to run a complete 100% realistic test, because some of the actions may influence behaviour as a result of success or not. The following differences apply: - Recipes with multiple commands, where later commands are only executed if all earlier commands were succesful are always succesful. This means that an action line (explanation see below) like ::REQUEST ::RETURNRECEIPT 7 vacation.txt vacation.db which sends a return receipt if the ::REQUEST command was succesful - the user is known will execute the ::RETURNRECEIPT 7 vacation.txt in test mode, even if ::REQUEST would have been unsuccesful. In this case, nothing is executed so it is no big deal. - Some actions may be able to fail but will always succeed or fail when in 'test' mode. As a result, a complete recipe will be succesful, whereas in 'active' mode it would have failed. As a result, the message will be considered delivered and no more recipes will be executed, whereas in 'active' mode the next recipe would be executed. ADDING PEOPLE TO THE ACCEPT DATABASE Normally, when someone who is not in the accept database sends you a message, they will get a message from GORD asking them to authenticate themselves. They will only get this message once, but even then, you might want to install and immediately add several known people. For this, you can use the add_db program, as in: /usr/local/gord/bin/add_db --dbtype=accept --from=Gerben_Wierda@RnA.nl FILTERING The basic GORD system works almost without filtering. But it can do heavy filtering if needed. There are two types of filters: 1. System-wide filters (mainly used to catch bounces from GORD requests). These filters are in the file /usr/local/lib/gord/recipes.ascii (human readable version) and /usr/local/lib/gord/recipes.db. The filters in the ascii file are loaded into the db with the command load_recipes --system 2. Per-user filters (mainly used to prevent mailing list stuff from reaching the accept/request phase). These filters are found in every user's .gord directory in the file ~/.gord/recipes.ascii (human readable version). They are loaded in the recipe database by running load_recipes The filter recipe consist of three parts: Regex matches on the header Regex matches on the body Actions Filters in ASCII format look like this ::BEGIN ::HEADER ::BODY ::ACTION actions taken if matches succesful ::END All regular expressions of a recipe must match for a recipe if the actions are to be performed. All actions must be succesful for the recipe to have succeeded. As soon as a recipe succeeds, the message is supposed to have been delivered. If there is no action line, the default is to deliver in the user's mailbox. THE REGULAR EXPRESSIONS The regular expressions used for matching against header or body (depending on their location in the recipe) are perl-style regular expressions. See the perlre man page for details. There are two modifiers that may be placed before the regular expression: ::NOT Demands a failure of this regular expression match on all lines (in header or body) ::NOCASE Does case-insensitive matching. THE ACTIONS The action lines may have the following formats: There are two per-action-line modifiers : ::RAW Just dump the message raw. Otherwise, assume BSD mbox format, including escaping From in the body. The default is that the message is dumped to a file or command in mbox format. ::IGNORE Ignore the succes or failure of this action line (it always succeeds). There are the following types of action >string write to file called string (overwrite!) >>string append to file called string |string pipe to program called string string append to mailbox called string, this is equivalent to >>string ::REQUEST Start the save/request cycle, or deliver if known sender. This action is succesful, unless there is no From: address. ::KILL Drop silently. This is in fact a no-op. It just returns success. If used as a single action it works as a 'drop silently' ::ACCEPTSENDER Accept this sender ::FAIL Force failure of this action ::RETURNRECEIPT n messagefile dbfile Send a return-receipt at most every n days. (see below for explanation). A header like X-MFA-Return-Receipt-By: GORD (SYSID) $VERSION will be added, so loop checking can be enabled. The filename must be available in the user's private GORD directory and contains the text to send. The dbfile is used to keep track of people who have gotten a message. ::ADDHEADER Addheader gobbles the rest of the action line up and adds it to the message header as is. Be careful with this one. An action line has succeeded if all the actions were succesful. A recipe has succeeded if all action lines have succeededIf a recipe succeeds, the message is supposed to be handled and no more recipes will be executed. Therefore, a single action line in a recipe with a ::KILL statement, silently drops the message. But so does a single line with an ::IGNORE statement somewhere. And so does a single line with just ::ACCEPTSENDER (if nothing goes wrong internally), because normally ::ACCEPTSENDER always succeeds. As will ::ADDHEADER. The following recipe will silently drop ALL messages: ::BEGIN ::HEADER . ::ACTION ::ADDHEADER My-Header: Hello there! ::END BOUNCES THAT DO NOT INCLUDE THE HEADER Some mailer daemons do not return the headers of the message that failed. As a result, the normal way to catch bounces that are the result of GORD-requests: ::BEGIN ::HEADER ::NOCASE ^From:.*(DAEMON|MAILER)@ ::BODY ::NOCASE ^X-Gord-Request:\s*\(\d+\.\d+\)\s*\(RnA\.nl\) ::ACTION ::KILL ::END does not work. A good example is the daemon from compuserve. As a result, a message form such a daemon will not be recognized and end up in the ::REQUEST process. This then generates a GORD request message for that mailer. There are several obvious ways to handle this. Gord has system-wide recipes that can handle this. Like: ::BEGIN ::HEADER ^Subject: Undeliverable Message ^Sender: CompuServe Postmaster ::BODY ::NOCASE ^X-Gord-Request:\s*\(\d+\.\d+\)\s*\(RnA\.nl\) ::ACTION ::KILL ::END USING A RECIPE THAT ACCEPTS ALL MAIL REALLY ADDRESSED TO YOU Since spammers normally do not generate a vaild To: field containing your real email address, you could use a recipe to accept all mail that is really addressed to you: ::BEGIN ::HEADER ::NOCASE ^(To|Cc):.*your_address@your_site ::BODY ::ACTION ::END This has the advantage of not immediately having to annoy all the people that send you mail with administrative actions. On the other hand, spammers will soon discover this potential leak and start sending individual messages with individual To: headers. So, you might have to skip this method in the end. It is particularly handy to start your collection of acceptable email addresses that way. Suppose you use the following recipe in your set. ::BEGIN ::HEADER ::NOCASE ^(To|Cc):.*your_address@your_site ::BODY ::ACTION ::ACCEPTSENDER ::FAIL ::END This will add the sender to your accept list (on the basis that this sender used your email address properly) and then the receipe fails, handling the rest later. You could even start a while with this recipe before all your mailing list recipes and collect their from-addresses for a while before moving to strict mode. It is probably most friendly to run like this for a while before really truning GORD to the strict and nasty mode without such a recipe. It is also possible of course to add the ::ACCEPTSENDER action to mailing list handling. Thus automatically adding subscribers to your accept list. WHAT TO DO WHEN YOU WANT TO SUBSCRIBE TO A MAILING LIST Each mailing list you are subscribed to needs a special recipe. That is because you do not know who will be posting to it and you want to accept everything posted on the list. What you have to do, is the folllowing series of actions: 1. Temporarily turn off GORD for you. Run gord_use inactive 2. Subscribe to the mailing list 3. When the first posting arrives, create a new entry in your recipes.ascii file. In that recipe, recognize the special entry that defines a message from the list, as in: ::BEGIN ::HEADER ^Sender: owner-liste@nexttoyou\.de ::BODY ::ACTION |/usr/local/bin/appnmail MailingLists/NEXTTOYOU ::END In this example, I pipe the message to a program that writes it to NeXTmail style message boxes, but you could of course just enter a file there which will then be the mailbox file for that mailing list. Note that if you are a client of an ISP and read your mail using POP3, using multiple mailboxes is somewhat of a no go. SOME WAYS IN WHICH SPAMMERS COULD ATTACK Spammers can do something about this system by starting to mail to mailing lists. If this system is succesful, this will put pressure on mailing lists to become moderated, which is a trend anyway. Spammers could also fake these maling list message headers. This is especially nasty if the spammers could request the list of subscribers of a mailing list so they know what people have to accept messages from which list. Requesting the list of subscribers is a breach of privacy, so it should not be possible. Well, internet has to mature anyway ;-) Spammers could add multiple headers for every known mailing list. For those, gord could be changed to stop messages with too many equivalent type headers. You can decide to install a non-strict version by creating a recipe for mail that is really directed to you, as descibed above. Most spammers do not send individual messages (they bulk-mail). If they start to do this, this trick to be friendly will not work anymore. Spammers could also decide to use a From: address that *is* valid but is just not their own. The point is: it would not help them as the request would end up somewhere else. But it could produce a lot of invalid acceptance requests. Spamers cannot forge requests and put their spam message in the body. The body of a request is suppressed by GORD and it is only seen by people who do not have GORD installed. THE WORST ATTACK OF ALL Actually, the worst attack of all would put your own email address in the From: header, which would make the message seem to come from yourself. This is the worst possible attack, as you do want to be able to receive messages from yourself. This assumes of course the worst scenario's for spamming: individual messages instead of bulk mail. And as long as GORD is not widely used, we might not see this attack. But when GORD or something like it does become succesful, it will appear. The only way to guard against this with the GORD system is to catch spoofs which can be recognized if all messages from the outside by definition pass a certain system (for instance your provider or a firewall). Any message that contains a From: address from within and a Received-By: header from the outside is a spoof. As outside intermediaries always add these headers, this spoof detection will work. The downside is that you can only test for this *after* all mailing lists, because messages returning from mailing lists may legitemately come from the outside with an inside From: address. Therefore, if this kind of attack becomes common, it will be necessary for all spam-guarded users to have at least one anti-spam filter recipe. Maybe in the future, anto-spoof will be built into the generic system. So, my personal filters contain the following recipes after the mailing list recipes: ==================================================== ::BEGIN ::HEADER ^Received: .+by eyor\.wiwo\.nl ::NOCASE ^From: .+@([^.]+\.)*rna\.nl ::NOT ::NOCASE ^Resent-From: ::ACTION ::ADDHEADER X-MFA-Spoofed: Message spoofed inside from-address GORD/Spoofs ::KILL ::END ::BEGIN ::HEADER ^Received: .+by eyor\.wiwo\.nl ::NOCASE ^Resent-From: .+@([^.]+\.)*rna\.nl ::ACTION ::ADDHEADER X-MFA-Spoofed: Message spoofed inside from-address GORD/Spoofs ::KILL ::END ==================================================== This mail catches spoofs, but the possibility of such a recipe depends on your mail setup. If someone knows a better answer, please tell me. EXAMPLE FILTER SETUPS WITH COMMENTS: For the system wide filters, I currently use: ==================================================== #Recipes for user __GORD__: #Generated by dump_recipes at Tue Sep 15 22:55:49 1998 ::BEGIN ::HEADER ::NOCASE ^(From|Sender):.*(d(ae|ea)mon|mailer)@ ::BODY ^Subject: GORD CR:\s*\(\d+\.\d+\)\s*\(RnA\.nl\)\s*\(\S+\) ::ACTION ::KILL ::END ::BEGIN ::HEADER ::NOCASE ^(From|Sender):.+(postmaster|sysadmin)@ ::NOCASE ^Subject:.+(returned|(non|un)deliverable|delivery failure) ::BODY ^Subject: GORD CR:\s*\(\d+\.\d+\)\s*\(RnA\.nl\)\s*\(\S+\) ::ACTION ::KILL ::END ::BEGIN ::HEADER ^Subject: Undeliverable Message ^Sender: CompuServe Postmaster ::BODY ^Subject: GORD CR:\s*\(\d+\.\d+\)\s*\(RnA\.nl\)\s*\(\S+\) ::ACTION ::KILL ::END ==================================================== Example personal filters: ==================================================== ::USER gerben ::BEGIN ::HEADER ^From:\s*\"L-Soft list server at popiejopie ::BODY ::ACTION MailingLists/popiejopie ::END ::BEGIN ::HEADER ^Sender:\s*owner-some-list@some\.org ::BODY ::ACTION ::ACCEPTSENDER MailingLists/Some-List ::END # The next filter I put in for testing, I save the message and then # do the action which would have been performed anyway. # This recipe matches any message ('.'). This setup drops all spam and all # denied messages into a special mailbox. # This example writes BSD-style mailboxes. ::BEGIN ::HEADER . ::BODY ::ACTION Mailboxes/GORD/Dropped ::REQUEST ::END ==================================================== SENDING CONFIRMATIONS TO ACCEPTED USERS Just create a file called confirm.txt in your personal .gord subdirectory. The contents will be used as body for a message sent after succeful handling of a reply to a GORD request. The text in the file will be modified. The following strings will be replaced: USER by your username SUBJECT by the subject of the message received FROM by the address of the person that mailed you. RETURNING RECEIPTS FOR RECEIVED MESSAGES You can force GORD to send a return-receipt for messages received. This can be used for instance instead of the well-known "vacation" program. Sending these receipts consists of two steps: 1. Create a file in your personal .gord subdirectory. 2. Add the action ::RETURNRECEIPT n filename dbfilename to the recipe for which you want to send receipts and reload the recipes. The character 'n' should be replaced with a number. This number stands for the minimum number of days between such receipts for everyone that has sent a message to you. E.g. ::RETURNRECEIPT 7 vacation.txt vacation.db will send not more than one such a return-receipt using the files vacation.txt and vacation.db (created by GORD) every week, and ::RETURNRECEIPT 0 ack.txt ack.db will send one for every received message for which this action line is executed, using the file ack.txt and the dbfile ack.db The text in the file will be modified. The following strings will be replaced: USER by your username SUBJECT by the subject of the message received FROM by the address of the person that mailed you. Since you do not want to send receipts to spammers and unknown senders, you should normally prefix this command with the ::IN command: ::BEGIN ::HEADER . ::ACTION ::IGNORE ::IN accept ::RETURNRECEIPT 7 vacation.txt vacation.db ::REQUEST ::END GORD will not generate auto-replies if any of the following _headers_ is available in the incoming message (this is built in): X-Loop: X-Mfa-Request-By: X-Mfa-Return-Receipt-By: X-Mfa-Confirmation-By: This prevents mail loops. To catch endless loops, you might want to catch the delivery failures of return-receipts and confirmations in your system recipes. CLOSING REMARKS (KNOWN BUGS ETC) SYSV IPC Under a very heavy load, my NEXTSTEP 3.3 systems fails in the networking code. This crashes my system. Also, under heavy load, my perl server program will hang and will only be killable by a SIGKILL. These errors originate in the OS. I have added System V IPC handling to limit access to the server program. Very stable systems may do without the SysVIPC. You can choose semaphores at installation time. Anyway, it works like this: The server creates a semaphore with value 4 (configurable) The clients use this semaphore to limit concurrent access to the server As a result I can start a 100 background jobs trying to deliver a message and the server will not die and the system will not crash. Perl users on systems without SysVIPC may use (after a little adaptation) this system, it is only to get around bugs on my system. LIMITATIONS Only knows about ordinary BSD mailboxes. Doesn't know about mh-style mailboxes. But it also doesn't know about NeXTmail mailboxes (which I use) but it is useful anyway since it can pipe to programs that do know about those. See the BUGS file for current bugs. MY ADDRESS Gerben_Wierda@RnA.nl