diff --git a/bgpwtf/cccampix/ripe-sync.py b/bgpwtf/cccampix/ripe-sync.py
new file mode 100644
index 0000000..116158c
--- /dev/null
+++ b/bgpwtf/cccampix/ripe-sync.py
@@ -0,0 +1,226 @@
+"""
+Updates IRR objects in RIPE for the CCCamp IX.
+
+This, given a mntner password and a list of ASNs taking part in the IXP will
+ensure the right IRR objects are present:
+
+ - an aut-num containing import/export RPSL rules
+ - an as-set containing all member ASs.
+
+
+"""
+
+import difflib
+import string
+import sys
+import time
+
+import grpc
+import requests
+
+from bgpwtf.cccampix.proto import ix_pb2 as ipb
+from bgpwtf.cccampix.proto import ix_pb2_grpc as ipb_grpc
+
+
+class IRRObject:
+    """An IRR object from RIPE."""
+    TYPE = None
+    def __init__(self, fields=None):
+        self.fields = fields or []
+
+    def add(self, k, v):
+        self.fields.append((k, v))
+
+    def render(self):
+        """Render to IRR format."""
+        return '\n'.join('{:16s}{}'.format(k+":", v) for k, v in self.fields) + "\n"
+
+    @classmethod
+    def from_ripe(cls, v):
+        """Download this object from the RIPE REST API."""
+        if cls.TYPE is None:
+            raise Exception('cannot fetch untyped IRRObject')
+
+        r = requests.get('https://rest.db.ripe.net/ripe/{}/{}.json'.format(cls.TYPE, v))
+        d = r.json()
+
+        obj = d['objects']['object'][0]
+        assert obj['type'] == cls.TYPE
+        assert obj['primary-key']['attribute'][0]['value'] == v
+
+        attrs = obj['attributes']['attribute']
+
+        fields = []
+        for attr in attrs:
+            # Skip metadata.
+            if attr['name'] in ('created', 'last-modified'):
+                continue
+            fields.append((attr['name'], attr['value']))
+
+        return cls(fields)
+
+    def send_to_ripe(self, password):
+        """Update this object (or create new) in RIPE using the SyncUpdates API."""
+        res = self.render()
+        res += 'password:       {}\n'.format(password)
+
+        data = {
+            'DATA': res,
+        }
+        r = requests.post('http://syncupdates.db.ripe.net/', files=data)
+        res = r.text
+        if 'Modify SUCCEEDED' not in res:
+            print(res)
+            raise Exception("Unexpected result from RIPE syncupdates")
+
+
+banner = [
+    ('remarks', r".--------------------------------------."),
+    ('remarks', r"|   _                         _    __  |"),
+    ('remarks', r"|  | |__   __ _ _ ____      _| |_ / _| |"),
+    ('remarks', r"|  | '_ \ / _` | '_ \ \ /\ / / __| |_  |"),
+    ('remarks', r"|  | |_) | (_| | |_) \ V  V /| |_|  _| |"),
+    ('remarks', r"|  |_.__/ \__, | .__(_)_/\_/  \__|_|   |"),
+    ('remarks', r"|         |___/|_|                     |"),
+    ('remarks', r"|--------------------------------------|"),
+    ('remarks', r"|  CCCamp2019 Internet Exchange Point  |"),
+    ('remarks', r"'--------------------------------------'"),
+    ('remarks', r''),
+    ('remarks', r'// 21. - 25. August 2019'),
+    ('remarks', r'// Ziegeleipark Mildenberg, Zehdenick, Germany, Earth, Milky Way'),
+    ('remarks', r'// Join us: https://bgp.wtf/cccamp19'),
+    ('remarks', r''),
+]
+
+
+class IXPAutNum(IRRObject):
+    """An aut-num (AS) object."""
+    TYPE = 'aut-num'
+    @classmethod
+    def make_for_members(cls, members):
+        fields = [
+            ('aut-num', 'AS208521'),
+            ('as-name', 'BGPWTF-CCCAMP19-IX'),
+        ] + banner + [
+            ('remarks', '// Current members:'),
+        ]
+
+        for member in sorted(list(members)):
+            fields.append(('import', 'from {} accept {}'.format(member, member)))
+            fields.append(('export', 'to {} announce AS-CCCAMP19-IX'.format(member)))
+
+        fields += [
+            ('remarks', ''),
+            ('remarks', '// Abuse: noc@hackerspace.pl'),
+            ('org', 'ORG-SH103-RIPE'),
+            ('admin-c', 'HACK2-RIPE'),
+            ('tech-c', 'HACK2-RIPE'),
+            ('status', 'ASSIGNED'),
+            ('mnt-by', 'RIPE-NCC-END-MNT'),
+            ('mnt-by', 'BGPWTF-AUTOMATION'),
+            ('mnt-by', 'pl-hs-1-mnt'),
+            ('source', 'RIPE'),
+        ]
+
+        return cls(fields)
+
+
+class ASSet(IRRObject):
+    """An as-set object."""
+    TYPE = 'as-set'
+    @classmethod
+    def make_for_members(cls, members):
+        fields = [
+            ('as-set', 'AS-CCCAMP19-IX'),
+            ('admin-c', 'HACK2-RIPE'),
+        ] + banner + [
+            ('remarks', '// Current members:'),
+        ]
+
+        for member in sorted(list(members)):
+            fields.append(('members', member))
+
+        fields += [
+            ('remarks', ''),
+            ('remarks', '// Abuse: noc@hackerspace.pl'),
+            ('tech-c', 'HACK2-RIPE'),
+            ('mnt-by', 'BGPWTF-AUTOMATION'),
+            ('mnt-by', 'pl-hs-1-mnt'),
+            ('source', 'RIPE'),
+        ]
+
+        return cls(fields)
+
+
+def sync(want, got, password, force):
+    """Sync an object if there is a diff to its current state."""
+    wantr = want.render().split('\n')
+    gotr = got.render().split('\n')
+
+    d = list(difflib.unified_diff(gotr, wantr, fromfile='got', tofile='want'))
+    fields_diff = set()
+    for dd in d:
+        if dd.startswith('---'):
+            continue
+        if dd.startswith('+++'):
+            continue
+        if not dd.startswith('+') and not dd.startswith('-'):
+            continue
+
+        field = dd[1:].split(':')[0]
+        fields_diff.add(field)
+
+    # We ignore remarks field changes, because the RIPE API returns us them always
+    # mangled (with spaces missing in the ASCII art).
+    if list(fields_diff) == ['remarks'] and not force:
+        print('No changes.')
+        return
+
+    if force:
+        print('Forcing update')
+    else:
+        print('Diff:')
+        print('\n'.join(d))
+    want.send_to_ripe(password)
+    print('Updated.')
+
+
+def sync_autnum(members, password, force=False):
+    print('Syncing aut-num...')
+    want = IXPAutNum.make_for_members(members)
+    got = IXPAutNum.from_ripe('AS208521')
+    sync(want, got, password, force)
+
+
+
+def sync_asset(members, password, force=False):
+    print('Syncing as-set...')
+    want = ASSet.make_for_members(members)
+    got = ASSet.from_ripe('AS-CCCAMP19-IX')
+    sync(want, got, password, force)
+
+
+
+if __name__ == '__main__':
+    if len(sys.argv) != 3:
+        print("Usage: {} <password> <verifier addr>".format(sys.argv[0]))
+        sys.exit(1)
+
+    password = sys.argv[1]
+    verifier = sys.argv[2]
+
+    chan = grpc.insecure_channel(verifier)
+    stub = ipb_grpc.VerifierStub(chan)
+
+    req = ipb.PeerSummaryRequest()
+    peers = stub.PeerSummary(req)
+
+    members = []
+    for peer in peers:
+        if peer.check_status != peer.STATUS_OK:
+            continue
+        members.append('AS'+str(peer.peeringdb_info.asn))
+
+    print("Members:", members)
+    sync_autnum(members, password)
+    sync_asset(members, password)
