diff --git a/tests/models/test_services.py b/tests/models/test_services.py
index 82808db46dfd0bd71ebeb7f5462093de5cdf0208..d6836b5f7d3d8dfbb329d639b29415e7491ee374 100644
--- a/tests/models/test_services.py
+++ b/tests/models/test_services.py
@@ -1,3 +1,5 @@
+import itertools
+
 from uffd.remailer import remailer
 from uffd.tasks import cleanup_task
 from uffd.database import db
@@ -39,6 +41,24 @@ class TestServiceUser(UffdTestCase):
 		db.session.commit()
 		self.assertEqual(ServiceUser.query.count(), service_count  * user_count)
 
+	def test_effective_remailer_mode(self):
+		self.app.config['REMAILER_DOMAIN'] = 'remailer.example.com'
+		user = self.get_user()
+		service = Service.query.filter_by(name='service1').first()
+		service.remailer_mode = RemailerMode.ENABLED_V2
+		service_user = ServiceUser.query.get((service.id, user.id))
+		self.assertEqual(service_user.effective_remailer_mode, RemailerMode.ENABLED_V2)
+		self.app.config['REMAILER_LIMIT_TO_USERS'] = ['testadmin']
+		self.assertEqual(service_user.effective_remailer_mode, RemailerMode.DISABLED)
+		self.app.config['REMAILER_LIMIT_TO_USERS'] = ['testuser']
+		self.assertEqual(service_user.effective_remailer_mode, RemailerMode.ENABLED_V2)
+		self.app.config['REMAILER_LIMIT_TO_USERS'] = None
+		service_user.remailer_overwrite_mode = RemailerMode.ENABLED_V1
+		service.remailer_mode = RemailerMode.DISABLED
+		self.assertEqual(service_user.effective_remailer_mode, RemailerMode.ENABLED_V1)
+		self.app.config['REMAILER_DOMAIN'] = ''
+		self.assertEqual(service_user.effective_remailer_mode, RemailerMode.DISABLED)
+
 	def test_service_email(self):
 		user = self.get_user()
 		service = Service.query.filter_by(name='service1').first()
@@ -99,119 +119,59 @@ class TestServiceUser(UffdTestCase):
 		# 5. remailer setup + remailer enabled + REMAILER_LIMIT_TO_USERS includes user
 		self.app.config['REMAILER_LIMIT_TO_USERS'] = ['testuser']
 		self.assertEqual(service_user.email, remailer_email)
+		# 6. remailer setup + remailer disabled + user overwrite
+		self.app.config['REMAILER_LIMIT_TO_USERS'] = None
+		service.remailer_mode = RemailerMode.DISABLED
+		service_user.remailer_overwrite_mode = RemailerMode.ENABLED_V1
+		self.assertEqual(service_user.email, remailer_email)
+		# 7. remailer setup + remailer enabled + user overwrite
+		self.app.config['REMAILER_LIMIT_TO_USERS'] = None
+		service.remailer_mode = RemailerMode.ENABLED_V1
+		service_user.remailer_overwrite_mode = RemailerMode.DISABLED
+		self.assertEqual(service_user.email, user.primary_email.address)
 
 	def test_filter_query_by_email(self):
-		def run_query(value):
-			return {(su.service_id, su.user_id) for su in ServiceUser.filter_query_by_email(ServiceUser.query, value)}
-
-		user1 = self.get_user()
-		user2 = User(loginname='user2', primary_email_address=user1.primary_email.address, displayname='User 2')
-		db.session.add(user2)
-		db.session.commit()
-		service1 = Service.query.filter_by(name='service1').first() # remailer disabled
-		service2 = Service.query.filter_by(name='service2').first() # remailer enabled
-		self.app.config['REMAILER_DOMAIN'] = 'remailer.example.com'
-		remailer_email1_1 = remailer.build_v1_address(service1.id, user1.id)
-		remailer_email2_1 = remailer.build_v1_address(service2.id, user1.id)
-		remailer_email1_2 = remailer.build_v1_address(service1.id, user2.id)
-		remailer_email2_2 = remailer.build_v1_address(service2.id, user2.id)
-
-		# 1. remailer disabled
-		self.app.config['REMAILER_DOMAIN'] = ''
-		self.assertEqual(run_query(user1.primary_email.address), {
-			(service1.id, user1.id), (service1.id, user2.id),
-			(service2.id, user1.id), (service2.id, user2.id),
-		})
-		self.assertEqual(run_query(remailer_email1_1), set())
-		self.assertEqual(run_query(remailer_email2_1), set())
-		self.assertEqual(run_query('invalid'), set())
-
-		# 2. remailer enabled + REMAILER_LIMIT_TO_USERS unset
-		self.app.config['REMAILER_DOMAIN'] = 'remailer.example.com'
-		self.assertEqual(run_query(user1.primary_email.address), {
-			(service1.id, user1.id), (service1.id, user2.id),
-		})
-		self.assertEqual(run_query(remailer_email1_1), set())
-		self.assertEqual(run_query(remailer_email2_1), {
-			(service2.id, user1.id),
-		})
-		self.assertEqual(run_query(remailer_email2_1 + ' '), set())
-		self.assertEqual(run_query('invalid'), set())
-
-		# 3. remailer enabled + REMAILER_LIMIT_TO_USERS includes testuser
-		self.app.config['REMAILER_LIMIT_TO_USERS'] = ['testuser']
-		self.assertEqual(run_query(user1.primary_email.address), {
-			(service1.id, user1.id), (service1.id, user2.id),
-			(service2.id, user2.id),
-		})
-		self.assertEqual(run_query(remailer_email1_1), set())
-		self.assertEqual(run_query(remailer_email2_1), {
-			(service2.id, user1.id),
-		})
-		self.assertEqual(run_query(remailer_email2_1 + ' '), set())
-		self.assertEqual(run_query(remailer_email1_2), set())
-		self.assertEqual(run_query(remailer_email2_2), set())
-		self.assertEqual(run_query('invalid'), set())
-
-		# 4. remailer enabled + REMAILER_LIMIT_TO_USERS does not include user (should behave the same as 1.)
-		self.app.config['REMAILER_LIMIT_TO_USERS'] = ['testadmin']
-		self.assertEqual(run_query(user1.primary_email.address), {
-			(service1.id, user1.id), (service1.id, user2.id),
-			(service2.id, user1.id), (service2.id, user2.id),
-		})
-		self.assertEqual(run_query(remailer_email1_1), set())
-		self.assertEqual(run_query(remailer_email2_1), set())
-		self.assertEqual(run_query('invalid'), set())
-
-	def test_filter_query_by_email_prefs(self):
-		def run_query(value):
-			return {(su.service_id, su.user_id) for su in ServiceUser.filter_query_by_email(ServiceUser.query, value)}
-
-		user1 = self.get_user()
-		service1 = Service.query.filter_by(name='service1').first() # remailer disabled
-		service2 = Service.query.filter_by(name='service2').first() # remailer enabled
-		self.app.config['REMAILER_DOMAIN'] = 'remailer.example.com'
-		remailer_email1_1 = remailer.build_v1_address(service1.id, user1.id)
-		remailer_email2_1 = remailer.build_v1_address(service2.id, user1.id)
-
-		self.app.config['REMAILER_DOMAIN'] = ''
-		self.assertEqual(run_query(user1.primary_email.address), {
-			(service1.id, user1.id),
-			(service2.id, user1.id),
-		})
-		self.assertEqual(run_query('addr1-1@example.com'), set())
-		self.assertEqual(run_query('addr2-1@example.com'), set())
-		self.assertEqual(run_query(remailer_email1_1), set())
-		self.assertEqual(run_query(remailer_email2_1), set())
-
-		ServiceUser.query.get((service1.id, user1.id)).service_email = UserEmail(user=user1, verified=True, address='addr1-1@example.com')
-		ServiceUser.query.get((service2.id, user1.id)).service_email = UserEmail(user=user1, verified=True, address='addr2-1@example.com')
-		self.assertEqual(run_query(user1.primary_email.address), {
-			(service1.id, user1.id),
-			(service2.id, user1.id),
-		})
-		self.assertEqual(run_query('addr1-1@example.com'), set())
-		self.assertEqual(run_query('addr2-1@example.com'), set())
-		self.assertEqual(run_query(remailer_email1_1), set())
-		self.assertEqual(run_query(remailer_email2_1), set())
-		service1.enable_email_preferences = True
-		service2.enable_email_preferences = True
-		self.assertEqual(run_query(user1.primary_email.address), set())
-		self.assertEqual(run_query('addr1-1@example.com'), {
-			(service1.id, user1.id),
-		})
-		self.assertEqual(run_query('addr2-1@example.com'), {
-			(service2.id, user1.id),
-		})
-		self.assertEqual(run_query(remailer_email1_1), set())
-		self.assertEqual(run_query(remailer_email2_1), set())
+		service = Service.query.filter_by(name='service1').first()
+		user = self.get_user()
 		self.app.config['REMAILER_DOMAIN'] = 'remailer.example.com'
-		self.assertEqual(run_query(user1.primary_email.address), set())
-		self.assertEqual(run_query('addr1-1@example.com'), {
-			(service1.id, user1.id),
-		})
-		self.assertEqual(run_query('addr2-1@example.com'), set())
-		self.assertEqual(run_query(remailer_email1_1), set())
-		self.assertEqual(run_query(remailer_email2_1), {
-			(service2.id, user1.id),
-		})
+		remailer_email_v1 = remailer.build_v1_address(service.id, user.id)
+		remailer_email_v2 = remailer.build_v2_address(service.id, user.id)
+		email1 = user.primary_email
+		email2 = UserEmail(user=user, address='test2@example.com', verified=True)
+		db.session.add(email2)
+		service_user = ServiceUser.query.get((service.id, user.id))
+		all_service_users = ServiceUser.query.all()
+		cases = itertools.product(
+			# Input values
+			[
+				'test@example.com',
+				'test2@example.com',
+				'other@example.com',
+				remailer_email_v1,
+				remailer_email_v2,
+			],
+			# REMAILER_DOMAIN config
+			[None, 'remailer.example.com'],
+			# REMAILER_LIMIT config
+			[None, ['testuser', 'otheruser'], ['testadmin', 'otheruser']],
+			# service.remailer_mode
+			[RemailerMode.DISABLED, RemailerMode.ENABLED_V1, RemailerMode.ENABLED_V2],
+			# service.enable_email_preferences
+			[True, False],
+			# service_user.service_email
+			[None, email1, email2],
+			# service_user.remailer_overwrite_mode
+			[None, RemailerMode.DISABLED, RemailerMode.ENABLED_V1, RemailerMode.ENABLED_V2],
+		)
+		for options in cases:
+			value = options[0]
+			self.app.config['REMAILER_DOMAIN'] = options[1]
+			self.app.config['REMAILER_LIMIT_TO_USERS'] = options[2]
+			service.remailer_mode = options[3]
+			service.enable_email_preferences = options[4]
+			service_user.service_email = options[5]
+			service_user.remailer_overwrite_mode = options[6]
+			a = {result for result in all_service_users if result.email == value}
+			b = set(ServiceUser.filter_query_by_email(ServiceUser.query, value).all())
+			if a != b:
+				self.fail(f'{a} != {b} with ' + repr(options))
diff --git a/tests/views/test_services.py b/tests/views/test_services.py
index 1e57d8be565b242f1a96ba1474e0d2ee3888381e..a40e447f07702651163a20429bf80d2ef20a082c 100644
--- a/tests/views/test_services.py
+++ b/tests/views/test_services.py
@@ -1,5 +1,7 @@
 from flask import url_for
 
+from uffd.database import db
+from uffd.models import Service, ServiceUser, OAuth2Client, APIClient, RemailerMode
 from tests.utils import dump, UffdTestCase
 
 class TestServices(UffdTestCase):
@@ -96,3 +98,233 @@ class TestServices(UffdTestCase):
 		r = self.client.get(path=url_for('service.overview'), follow_redirects=True)
 		dump('service_overview_public_admin', r)
 		self.assertEqual(r.status_code, 200)
+
+class TestServiceAdminViews(UffdTestCase):
+	def setUpDB(self):
+		db.session.add(Service(
+			name='test1',
+			oauth2_clients=[OAuth2Client(client_id='test1_oauth2_client1', client_secret='test'), OAuth2Client(client_id='test1_oauth2_client2', client_secret='test')],
+			api_clients=[APIClient(auth_username='test1_api_client1', auth_password='test'), APIClient(auth_username='test1_api_client2', auth_password='test')],
+		))
+		db.session.add(Service(name='test2'))
+		db.session.add(Service(name='test3'))
+		db.session.commit()
+		self.service_id = Service.query.filter_by(name='test1').one().id
+
+	def test_index(self):
+		self.login_as('admin')
+		r = self.client.get(path=url_for('service.index'), follow_redirects=True)
+		dump('service_index', r)
+		self.assertEqual(r.status_code, 200)
+
+	def test_show(self):
+		self.login_as('admin')
+		r = self.client.get(path=url_for('service.show', id=self.service_id), follow_redirects=True)
+		dump('service_show', r)
+		self.assertEqual(r.status_code, 200)
+
+	def test_new(self):
+		self.login_as('admin')
+		r = self.client.get(path=url_for('service.show'), follow_redirects=True)
+		dump('service_new', r)
+		self.assertEqual(r.status_code, 200)
+
+	def test_new_submit(self):
+		self.login_as('admin')
+		r = self.client.post(
+			path=url_for('service.edit_submit'),
+			follow_redirects=True,
+			data={
+				'name': 'new-service',
+				'access-group': '',
+				'remailer-mode': 'DISABLED',
+				'remailer-overwrite-mode': 'ENABLED_V2',
+				'remailer-overwrite-users': '',
+			},
+		)
+		dump('service_new_submit', r)
+		self.assertEqual(r.status_code, 200)
+		service = Service.query.filter_by(name='new-service').one_or_none()
+		self.assertIsNotNone(service)
+		self.assertEqual(service.limit_access, True)
+		self.assertEqual(service.access_group, None)
+		self.assertEqual(service.remailer_mode, RemailerMode.DISABLED)
+		self.assertEqual(service.enable_email_preferences, False)
+
+	def test_edit(self):
+		self.login_as('admin')
+		r = self.client.post(
+			path=url_for('service.edit_submit', id=self.service_id),
+			follow_redirects=True,
+			data={
+				'name': 'new-name',
+				'access-group': '',
+				'remailer-mode': 'DISABLED',
+				'remailer-overwrite-mode': 'ENABLED_V2',
+				'remailer-overwrite-users': '',
+			},
+		)
+		dump('service_edit_submit', r)
+		self.assertEqual(r.status_code, 200)
+		service = Service.query.get(self.service_id)
+		self.assertEqual(service.name, 'new-name')
+		self.assertEqual(service.limit_access, True)
+		self.assertEqual(service.access_group, None)
+		self.assertEqual(service.remailer_mode, RemailerMode.DISABLED)
+		self.assertEqual(service.enable_email_preferences, False)
+
+	def test_edit_access_all(self):
+		self.login_as('admin')
+		r = self.client.post(
+			path=url_for('service.edit_submit', id=self.service_id),
+			follow_redirects=True,
+			data={
+				'name': 'test1',
+				'access-group': 'all',
+				'remailer-mode': 'DISABLED',
+				'remailer-overwrite-mode': 'ENABLED_V2',
+				'remailer-overwrite-users': '',
+			},
+		)
+		self.assertEqual(r.status_code, 200)
+		service = Service.query.get(self.service_id)
+		self.assertEqual(service.limit_access, False)
+		self.assertEqual(service.access_group, None)
+
+	def test_edit_access_group(self):
+		self.login_as('admin')
+		r = self.client.post(
+			path=url_for('service.edit_submit', id=self.service_id),
+			follow_redirects=True,
+			data={
+				'name': 'test1',
+				'access-group': str(self.get_users_group().id),
+				'remailer-mode': 'DISABLED',
+				'remailer-overwrite-mode': 'ENABLED_V2',
+				'remailer-overwrite-users': '',
+			},
+		)
+		self.assertEqual(r.status_code, 200)
+		service = Service.query.get(self.service_id)
+		self.assertEqual(service.limit_access, True)
+		self.assertEqual(service.access_group, self.get_users_group())
+
+	def test_edit_email_preferences(self):
+		self.login_as('admin')
+		r = self.client.post(
+			path=url_for('service.edit_submit', id=self.service_id),
+			follow_redirects=True,
+			data={
+				'name': 'test1',
+				'access-group': '',
+				'remailer-mode': 'DISABLED',
+				'remailer-overwrite-mode': 'ENABLED_V2',
+				'remailer-overwrite-users': '',
+				'enable_email_preferences': '1',
+			},
+		)
+		self.assertEqual(r.status_code, 200)
+		service = Service.query.get(self.service_id)
+		self.assertEqual(service.enable_email_preferences, True)
+
+	def test_edit_remailer_mode(self):
+		self.login_as('admin')
+		r = self.client.post(
+			path=url_for('service.edit_submit', id=self.service_id),
+			follow_redirects=True,
+			data={
+				'name': 'test1',
+				'access-group': '',
+				'remailer-mode': 'ENABLED_V2',
+				'remailer-overwrite-mode': 'ENABLED_V2',
+				'remailer-overwrite-users': '',
+			},
+		)
+		self.assertEqual(r.status_code, 200)
+		service = Service.query.get(self.service_id)
+		self.assertEqual(service.remailer_mode, RemailerMode.ENABLED_V2)
+
+	def test_edit_remailer_overwrite_enable(self):
+		self.login_as('admin')
+		r = self.client.post(
+			path=url_for('service.edit_submit', id=self.service_id),
+			follow_redirects=True,
+			data={
+				'name': 'test1',
+				'access-group': '',
+				'remailer-mode': 'DISABLED',
+				'remailer-overwrite-mode': 'ENABLED_V2',
+				'remailer-overwrite-users': 'testuser, testadmin',
+			},
+		)
+		self.assertEqual(r.status_code, 200)
+		service_user1 = ServiceUser.query.get((self.service_id, self.get_user().id))
+		service_user2 = ServiceUser.query.get((self.service_id, self.get_admin().id))
+		self.assertEqual(service_user1.remailer_overwrite_mode, RemailerMode.ENABLED_V2)
+		self.assertEqual(service_user2.remailer_overwrite_mode, RemailerMode.ENABLED_V2)
+		self.assertEqual(
+			set(ServiceUser.query.filter(
+				ServiceUser.service_id == self.service_id,
+				ServiceUser.remailer_overwrite_mode != None
+			).all()),
+			{service_user1, service_user2}
+		)
+
+	def test_edit_remailer_overwrite_change(self):
+		service_user = ServiceUser.query.get((self.service_id, self.get_user().id))
+		service_user.remailer_overwrite_mode = RemailerMode.ENABLED_V2
+		db.session.commit()
+		self.login_as('admin')
+		r = self.client.post(
+			path=url_for('service.edit_submit', id=self.service_id),
+			follow_redirects=True,
+			data={
+				'name': 'test1',
+				'access-group': '',
+				'remailer-mode': 'DISABLED',
+				'remailer-overwrite-mode': 'ENABLED_V1',
+				'remailer-overwrite-users': ', testadmin',
+			},
+		)
+		self.assertEqual(r.status_code, 200)
+		service_user = ServiceUser.query.get((self.service_id, self.get_admin().id))
+		self.assertEqual(service_user.remailer_overwrite_mode, RemailerMode.ENABLED_V1)
+		self.assertEqual(
+			ServiceUser.query.filter(
+				ServiceUser.service_id == self.service_id,
+				ServiceUser.remailer_overwrite_mode != None
+			).all(),
+			[service_user]
+		)
+
+	def test_edit_remailer_overwrite_disable(self):
+		service_user = ServiceUser.query.get((self.service_id, self.get_user().id))
+		service_user.remailer_overwrite_mode = RemailerMode.ENABLED_V2
+		db.session.commit()
+		self.login_as('admin')
+		r = self.client.post(
+			path=url_for('service.edit_submit', id=self.service_id),
+			follow_redirects=True,
+			data={
+				'name': 'test1',
+				'access-group': '',
+				'remailer-mode': 'DISABLED',
+				'remailer-overwrite-mode': 'ENABLED_V2',
+				'remailer-overwrite-users': '',
+			},
+		)
+		self.assertEqual(r.status_code, 200)
+		self.assertEqual(
+			ServiceUser.query.filter(
+				ServiceUser.service_id == self.service_id,
+				ServiceUser.remailer_overwrite_mode != None
+			).all(),
+			[]
+		)
+
+	def test_delete(self):
+		self.login_as('admin')
+		r = self.client.get(path=url_for('service.delete', id=self.service_id), follow_redirects=True)
+		dump('service_delete', r)
+		self.assertEqual(r.status_code, 200)
+		self.assertIsNone(Service.query.get(self.service_id))
diff --git a/uffd/default_config.cfg b/uffd/default_config.cfg
index 7b01157fb27e75cf264e21413a7f268c6c1f91c7..3ac6ee2160a78049bc7b465c7af6e78ebf01519a 100644
--- a/uffd/default_config.cfg
+++ b/uffd/default_config.cfg
@@ -53,7 +53,8 @@ REMAILER_OLD_DOMAINS = []
 REMAILER_SECRET_KEY = None
 # Set to list of user loginnames to limit remailer to a small list of users.
 # Useful for debugging. If None remailer is active for all users (if
-# configured and enabled for a service).
+# configured and enabled for a service). This option is deprecated. Use the
+# per-service setting in the web interface instead.
 REMAILER_LIMIT_TO_USERS = None
 
 # Do not enable this on a public service! There is no spam protection implemented at the moment.
diff --git a/uffd/migrations/versions/e249233e2a31_remailer_mode_overwrite.py b/uffd/migrations/versions/e249233e2a31_remailer_mode_overwrite.py
new file mode 100644
index 0000000000000000000000000000000000000000..10c617ee70e3f14d9be935cc4171724f36b5a666
--- /dev/null
+++ b/uffd/migrations/versions/e249233e2a31_remailer_mode_overwrite.py
@@ -0,0 +1,44 @@
+"""Remailer mode overwrite
+
+Revision ID: e249233e2a31
+Revises: aeb07202a6c8
+Create Date: 2022-11-05 03:42:38.036623
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+# revision identifiers, used by Alembic.
+revision = 'e249233e2a31'
+down_revision = 'aeb07202a6c8'
+branch_labels = None
+depends_on = None
+
+def upgrade():
+	meta = sa.MetaData(bind=op.get_bind())
+	service_user = sa.Table('service_user', meta,
+		sa.Column('service_id', sa.Integer(), nullable=False),
+		sa.Column('user_id', sa.Integer(), nullable=False),
+		sa.Column('service_email_id', sa.Integer(), nullable=True),
+		sa.ForeignKeyConstraint(['service_email_id'], ['user_email.id'], name=op.f('fk_service_user_service_email_id_user_email'), onupdate='CASCADE', ondelete='SET NULL'),
+		sa.ForeignKeyConstraint(['service_id'], ['service.id'], name=op.f('fk_service_user_service_id_service'), onupdate='CASCADE', ondelete='CASCADE'),
+		sa.ForeignKeyConstraint(['user_id'], ['user.id'], name=op.f('fk_service_user_user_id_user'), onupdate='CASCADE', ondelete='CASCADE'),
+		sa.PrimaryKeyConstraint('service_id', 'user_id', name=op.f('pk_service_user'))
+	)
+	with op.batch_alter_table('service_user', copy_from=service_user) as batch_op:
+		batch_op.add_column(sa.Column('remailer_overwrite_mode', sa.Enum('DISABLED', 'ENABLED_V1', 'ENABLED_V2', name='remailermode'), nullable=True))
+
+def downgrade():
+	meta = sa.MetaData(bind=op.get_bind())
+	service_user = sa.Table('service_user', meta,
+		sa.Column('service_id', sa.Integer(), nullable=False),
+		sa.Column('user_id', sa.Integer(), nullable=False),
+		sa.Column('remailer_overwrite_mode', sa.Enum('DISABLED', 'ENABLED_V1', 'ENABLED_V2', name='remailermode'), nullable=True),
+		sa.Column('service_email_id', sa.Integer(), nullable=True),
+		sa.ForeignKeyConstraint(['service_email_id'], ['user_email.id'], name=op.f('fk_service_user_service_email_id_user_email'), onupdate='CASCADE', ondelete='SET NULL'),
+		sa.ForeignKeyConstraint(['service_id'], ['service.id'], name=op.f('fk_service_user_service_id_service'), onupdate='CASCADE', ondelete='CASCADE'),
+		sa.ForeignKeyConstraint(['user_id'], ['user.id'], name=op.f('fk_service_user_user_id_user'), onupdate='CASCADE', ondelete='CASCADE'),
+		sa.PrimaryKeyConstraint('service_id', 'user_id', name=op.f('pk_service_user'))
+	)
+	with op.batch_alter_table('service_user', copy_from=service_user) as batch_op:
+		batch_op.drop_column('remailer_overwrite_mode')
diff --git a/uffd/models/service.py b/uffd/models/service.py
index c5e5cbcce58674c5c85be9b7b8e0b754d9952880..2143e6740fd119d39698bd465438ead46e23fb6d 100644
--- a/uffd/models/service.py
+++ b/uffd/models/service.py
@@ -58,6 +58,19 @@ class ServiceUser(db.Model):
 	def has_access(self):
 		return not self.service.limit_access or self.service.access_group in self.user.groups
 
+	remailer_overwrite_mode = Column(Enum(RemailerMode), default=None, nullable=True)
+
+	@property
+	def effective_remailer_mode(self):
+		if not remailer.configured:
+			return RemailerMode.DISABLED
+		if current_app.config['REMAILER_LIMIT_TO_USERS'] is not None:
+			if self.user.loginname not in current_app.config['REMAILER_LIMIT_TO_USERS']:
+				return RemailerMode.DISABLED
+		if self.remailer_overwrite_mode is not None:
+			return self.remailer_overwrite_mode
+		return self.service.remailer_mode
+
 	service_email_id = Column(Integer(), ForeignKey('user_email.id', onupdate='CASCADE', ondelete='SET NULL'))
 	service_email = relationship('UserEmail')
 
@@ -92,13 +105,9 @@ class ServiceUser(db.Model):
 	# E-Mail address as seen by the service
 	@property
 	def email(self):
-		if current_app.config['REMAILER_LIMIT_TO_USERS'] is None:
-			use_remailer = remailer.configured
-		else:
-			use_remailer = remailer.configured and self.user.loginname in current_app.config['REMAILER_LIMIT_TO_USERS']
-		if use_remailer and self.service.remailer_mode == RemailerMode.ENABLED_V1:
+		if self.effective_remailer_mode == RemailerMode.ENABLED_V1:
 			return remailer.build_v1_address(self.service_id, self.user_id)
-		if use_remailer and self.service.remailer_mode == RemailerMode.ENABLED_V2:
+		if self.effective_remailer_mode == RemailerMode.ENABLED_V2:
 			return remailer.build_v2_address(self.service_id, self.user_id)
 		return self.real_email
 
@@ -106,7 +115,7 @@ class ServiceUser(db.Model):
 	def filter_query_by_email(cls, query, email):
 		'''Filter query of ServiceUser by ServiceUser.email'''
 		# pylint completely fails to understand SQLAlchemy's query functions
-		# pylint: disable=no-member,invalid-name
+		# pylint: disable=no-member,invalid-name,singleton-comparison
 		service_user = cls.get_by_remailer_email(email)
 		if service_user and service_user.email == email:
 			return query.filter(cls.user_id == service_user.user_id, cls.service_id == service_user.service_id)
@@ -121,23 +130,26 @@ class ServiceUser(db.Model):
 		query = query.outerjoin(cls.service_email.of_type(AliasedServiceEmail))
 		query = query.join(cls.service.of_type(AliasedService))
 
-		remailer_enabled_expr = db.and_(
-			AliasedService.remailer_mode != RemailerMode.DISABLED,
-			remailer.configured
+		remailer_enabled = db.case(
+			whens=[
+				(db.not_(remailer.configured), False),
+				(
+					db.not_(AliasedUser.loginname.in_(current_app.config['REMAILER_LIMIT_TO_USERS']))
+						if current_app.config['REMAILER_LIMIT_TO_USERS'] is not None else db.and_(False),
+					False
+				),
+				(cls.remailer_overwrite_mode != None, cls.remailer_overwrite_mode != RemailerMode.DISABLED)
+			],
+			else_=(AliasedService.remailer_mode != RemailerMode.DISABLED)
 		)
-		if current_app.config['REMAILER_LIMIT_TO_USERS'] is not None:
-			remailer_enabled_expr = db.and_(
-				remailer_enabled_expr,
-				AliasedUser.loginname.in_(current_app.config['REMAILER_LIMIT_TO_USERS']),
-			)
-		real_email_matches_expr = db.case(
+		real_email_matches = db.case(
 			whens=[
 				# pylint: disable=singleton-comparison
 				(db.and_(AliasedService.enable_email_preferences, cls.service_email != None), AliasedServiceEmail.address == email),
 			],
 			else_=(AliasedPrimaryEmail.address == email)
 		)
-		return query.filter(db.and_(db.not_(remailer_enabled_expr), real_email_matches_expr))
+		return query.filter(db.and_(db.not_(remailer_enabled), real_email_matches))
 
 @db.event.listens_for(db.Session, 'after_flush') # pylint: disable=no-member
 def create_service_users(session, flush_context): # pylint: disable=unused-argument
diff --git a/uffd/templates/service/show.html b/uffd/templates/service/show.html
index 6c6fca94f8121b6e06ad228355d995e7c17e54d6..5277fa41751cfbc4fce96f2174ad05767ff652d5 100644
--- a/uffd/templates/service/show.html
+++ b/uffd/templates/service/show.html
@@ -21,7 +21,7 @@
 			<input type="text" class="form-control" id="service-name" name="name" value="{{ service.name or '' }}" required>
 		</div>
 		<div class="form-group col">
-			<label for="moderator-group">{{ _('Access Restriction') }}</label>
+			<label for="access-group">{{ _('Access Restriction') }}</label>
 			<select class="form-control" id="access-group" name="access-group">
 				<option value="" class="text-muted">{{ _('No user has access') }}</option>
 				<option value="all" class="text-muted" {{ 'selected' if not service.limit_access }}>{{ _('All users have access (legacy)') }}</option>
@@ -54,6 +54,30 @@
 			</small>
 		</div>
 
+		<div class="form-group col">
+			<p class="mb-2">
+				{{ _('Overwrite remailer setting for specific users') }}
+			</p>
+			<div class="input-group" id="remailer-mode-overwrite">
+				<input class="form-control" name="remailer-overwrite-users" placeholder="{{ _('Login names') }}" value="{{ remailer_overwrites|map(attribute='user')|map(attribute='loginname')|sort|join(', ') }}">
+				<select class="form-control" name="remailer-overwrite-mode">
+					{% set remailer_overwrite_mode = remailer_overwrites|map(attribute='remailer_overwrite_mode')|first or RemailerMode.ENABLED_V2 %}
+					<option value="{{ RemailerMode.DISABLED.name }}" {{ 'selected' if remailer_overwrite_mode == RemailerMode.DISABLED }}>
+						{{ _('Remailer disabled') }}
+					</option>
+					<option value="{{ RemailerMode.ENABLED_V2.name }}" {{ 'selected' if remailer_overwrite_mode == RemailerMode.ENABLED_V2 }}>
+						{{ _('Remailer enabled') }}
+					</option>
+					<option value="{{ RemailerMode.ENABLED_V1.name }}" {{ 'selected' if remailer_overwrite_mode == RemailerMode.ENABLED_V1 }}>
+						{{ _('Remailer enabled (deprecated, case-sensitive format)') }}
+					</option>
+				</select>
+			</div>
+			<small class="form-text text-muted">
+				{{ _('Useful for testing remailer before enabling it for all users. Specify users as a comma-seperated list of login names.') }}
+			</small>
+		</div>
+
 		<div class="form-group col">
 			<div class="form-check">
 				<input class="form-check-input" type="checkbox" id="service-enable-email-preferences" name="enable_email_preferences" value="1" aria-label="enabled" {{ 'checked' if service.enable_email_preferences }}>
diff --git a/uffd/translations/de/LC_MESSAGES/messages.mo b/uffd/translations/de/LC_MESSAGES/messages.mo
index f7010b8fa6548e32d0a8e5ebeb97cc081ca8d9c0..0897f2eba472b656935ffde9314eb66162e0fef2 100644
Binary files a/uffd/translations/de/LC_MESSAGES/messages.mo and b/uffd/translations/de/LC_MESSAGES/messages.mo differ
diff --git a/uffd/translations/de/LC_MESSAGES/messages.po b/uffd/translations/de/LC_MESSAGES/messages.po
index 52d52102f02e5d68cc23fe92e0f42937b072bc92..5738094ae9a4f4e90d9b1e17bf21e6891a065aa0 100644
--- a/uffd/translations/de/LC_MESSAGES/messages.po
+++ b/uffd/translations/de/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PROJECT VERSION\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2022-11-01 00:38+0100\n"
+"POT-Creation-Date: 2022-11-06 01:46+0100\n"
 "PO-Revision-Date: 2021-05-25 21:18+0200\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: de\n"
@@ -98,7 +98,7 @@ msgstr "Falsches Passwort"
 msgid "Login name or e-mail address is already in use"
 msgstr "Der Anmeldename oder die E-Mail-Adresse wird bereits verwendet"
 
-#: uffd/models/user.py:46
+#: uffd/models/user.py:119
 #, python-format
 msgid ""
 "At least %(minlen)d and at most %(maxlen)d characters. Only letters, "
@@ -144,8 +144,8 @@ msgstr "Über uffd"
 
 #: uffd/templates/group/list.html:8 uffd/templates/invite/list.html:6
 #: uffd/templates/mail/list.html:8 uffd/templates/role/list.html:8
-#: uffd/templates/service/index.html:8 uffd/templates/service/show.html:75
-#: uffd/templates/service/show.html:103 uffd/templates/user/list.html:8
+#: uffd/templates/service/index.html:8 uffd/templates/service/show.html:99
+#: uffd/templates/service/show.html:127 uffd/templates/user/list.html:8
 msgid "New"
 msgstr "Neu"
 
@@ -162,7 +162,7 @@ msgstr "GID"
 #: uffd/templates/rolemod/list.html:9 uffd/templates/rolemod/show.html:44
 #: uffd/templates/selfservice/self.html:189
 #: uffd/templates/service/index.html:14 uffd/templates/service/show.html:20
-#: uffd/templates/service/show.html:109 uffd/templates/user/show.html:193
+#: uffd/templates/service/show.html:133 uffd/templates/user/show.html:193
 #: uffd/templates/user/show.html:225
 msgid "Name"
 msgstr "Name"
@@ -238,7 +238,7 @@ msgid "Created by"
 msgstr "Erstellt durch"
 
 #: uffd/templates/invite/list.html:14 uffd/templates/service/api.html:34
-#: uffd/templates/service/show.html:110
+#: uffd/templates/service/show.html:134
 msgid "Permissions"
 msgstr "Berechtigungen"
 
@@ -1239,7 +1239,7 @@ msgstr "Diese Option hat keine Auswirkung: Remailer ist nicht konfiguriert"
 msgid "Access uffd metrics"
 msgstr "Zugriff auf uffd-Metriken"
 
-#: uffd/templates/service/oauth2.html:20 uffd/templates/service/show.html:81
+#: uffd/templates/service/oauth2.html:20 uffd/templates/service/show.html:105
 msgid "Client ID"
 msgstr "Client-ID"
 
@@ -1312,15 +1312,15 @@ msgstr "Mitglieder der Gruppe \"%(group_name)s\" haben Zugriff"
 msgid "Hide e-mail addresses with remailer"
 msgstr "E-Mail-Adressen mit Remailer verstecken"
 
-#: uffd/templates/service/show.html:43
+#: uffd/templates/service/show.html:43 uffd/templates/service/show.html:66
 msgid "Remailer disabled"
 msgstr "Remailer deaktiviert"
 
-#: uffd/templates/service/show.html:46
+#: uffd/templates/service/show.html:46 uffd/templates/service/show.html:69
 msgid "Remailer enabled"
 msgstr "Remailer aktiviert"
 
-#: uffd/templates/service/show.html:49
+#: uffd/templates/service/show.html:49 uffd/templates/service/show.html:72
 msgid "Remailer enabled (deprecated, case-sensitive format)"
 msgstr ""
 "Remailer aktiviert (veraltetes, Groß-/Kleinschreibung-unterscheidendes "
@@ -1337,13 +1337,29 @@ msgstr ""
 "-Mail-Adressen aller Nutzer aus und kann zu massenhaftem Versand von "
 "Benachrichtigungs-E-Mails führen."
 
-#: uffd/templates/service/show.html:60
+#: uffd/templates/service/show.html:59
+msgid "Overwrite remailer setting for specific users"
+msgstr "Überschreibe Remailer-Einstellung für ausgewählte Nutzer"
+
+#: uffd/templates/service/show.html:62
+msgid "Login names"
+msgstr "Anmeldenamen"
+
+#: uffd/templates/service/show.html:77
+msgid ""
+"Useful for testing remailer before enabling it for all users. Specify "
+"users as a comma-seperated list of login names."
+msgstr ""
+"Hilfreich zum Testen des Remailers vor dem Aktivieren für alle Nutzer. Um"
+" Nutzer auszuwählen, liste ihre Anmeldenamen mit Komma getrennt auf."
+
+#: uffd/templates/service/show.html:84
 msgid "Allow users to select a different e-mail address for this service"
 msgstr ""
 "Ermögliche Nutzern für diesen Dienst eine andere E-Mail-Adresse "
 "auszuwählen"
 
-#: uffd/templates/service/show.html:62
+#: uffd/templates/service/show.html:86
 msgid "If disabled, the service always uses the primary e-mail address."
 msgstr "Wenn deaktiviert, wird immer die primäre E-Mail-Adresse verwendet."
 
diff --git a/uffd/views/service.py b/uffd/views/service.py
index 7f5b36e03aaeeda3e2fb211751895f91bac74fe1..37fa1f67bedf10adab5c505cec021b117ed85737 100644
--- a/uffd/views/service.py
+++ b/uffd/views/service.py
@@ -6,7 +6,7 @@ from flask_babel import lazy_gettext
 from uffd.navbar import register_navbar
 from uffd.csrf import csrf_protect
 from uffd.database import db
-from uffd.models import Service, get_services, Group, OAuth2Client, OAuth2LogoutURI, APIClient, RemailerMode
+from uffd.models import User, Service, ServiceUser, get_services, Group, OAuth2Client, OAuth2LogoutURI, APIClient, RemailerMode
 
 from .session import login_required
 
@@ -50,8 +50,15 @@ def index():
 @login_required(admin_acl)
 def show(id=None):
 	service = Service() if id is None else Service.query.get_or_404(id)
+	remailer_overwrites = []
+	if id is not None:
+		# pylint: disable=singleton-comparison
+		remailer_overwrites = ServiceUser.query.filter(
+			ServiceUser.service_id == id,
+			ServiceUser.remailer_overwrite_mode != None
+		).all()
 	all_groups = Group.query.all()
-	return render_template('service/show.html', service=service, all_groups=all_groups)
+	return render_template('service/show.html', service=service, all_groups=all_groups, remailer_overwrites=remailer_overwrites)
 
 @bp.route('/service/new', methods=['POST'])
 @bp.route('/service/<int:id>', methods=['POST'])
@@ -73,8 +80,26 @@ def edit_submit(id=None):
 	else:
 		service.limit_access = True
 		service.access_group = Group.query.get(request.form['access-group'])
-	service.remailer_mode = RemailerMode[request.form['remailer-mode']]
 	service.enable_email_preferences = request.form.get('enable_email_preferences') == '1'
+	service.remailer_mode = RemailerMode[request.form['remailer-mode']]
+	remailer_overwrite_mode = RemailerMode[request.form['remailer-overwrite-mode']]
+	remailer_overwrite_user_ids = [
+		User.query.filter_by(loginname=loginname.strip()).one().id
+		for loginname in request.form['remailer-overwrite-users'].split(',') if loginname.strip()
+	]
+	# pylint: disable=singleton-comparison
+	service_users = ServiceUser.query.filter(
+		ServiceUser.service == service,
+		db.or_(
+			ServiceUser.user_id.in_(remailer_overwrite_user_ids),
+			ServiceUser.remailer_overwrite_mode != None,
+		)
+	)
+	for service_user in service_users:
+		if service_user.user_id in remailer_overwrite_user_ids:
+			service_user.remailer_overwrite_mode = remailer_overwrite_mode
+		else:
+			service_user.remailer_overwrite_mode = None
 	db.session.commit()
 	return redirect(url_for('service.show', id=service.id))