diff --git a/radius-client/defaults/main.yml b/radius-client/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5583865d503cba31411826e56a643a59bc142f5a
--- /dev/null
+++ b/radius-client/defaults/main.yml
@@ -0,0 +1,3 @@
+---
+
+radius_certs_dir: "{{ inventory_dir }}/files/radius-certs/"
diff --git a/radius-client/handlers/main.yml b/radius-client/handlers/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9314921dae72d1b6015b915e7508ab5952cc2557
--- /dev/null
+++ b/radius-client/handlers/main.yml
@@ -0,0 +1,14 @@
+---
+
+- name: reload systemd service files
+  command: systemctl daemon-reload
+
+- name: restart wpasupplicant@eth0
+  service: name=wpa_supplicant-wired@eth0 state=restarted
+
+- name: restart wpasupplicant@eth1
+  service: name=wpa_supplicant-wired@eth1 state=restarted
+
+- name: restart wpasupplicant@enp0s25
+  service: name=wpa_supplicant-wired@enp0s25 state=restarted
+
diff --git a/radius-client/tasks/main.yml b/radius-client/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..bf2ae310fa051bd91438e7dba8db38fbfa364f6f
--- /dev/null
+++ b/radius-client/tasks/main.yml
@@ -0,0 +1,54 @@
+---
+
+- name: ensure wpasupplicant is installed
+  apt:
+    name: wpasupplicant
+    state: present
+  tags:
+    - 8021x
+ 
+- name: copy host certificate
+  copy:
+    src: "{{ radius_certs_dir }}/{{ inventory_hostname }}.{{ item }}"
+    dest: "/etc/wpa_supplicant/{{ inventory_hostname }}.{{ item }}"
+    owner: root
+    group: root
+    mode: 0400
+  with_items:
+    - pem
+    - key
+  tags:
+    - 8021x
+
+- name: configure wpasupplicant
+  template:
+    src: wpa_supplicant.j2
+    dest: "/etc/wpa_supplicant/wpa_supplicant-wired-{{ ansible_default_ipv4.interface }}.conf"
+    owner: root
+    group: root
+    mode: 0640
+  notify:
+    - "restart wpasupplicant@{{ ansible_default_ipv4.interface }}"
+  tags:
+    - 8021x
+
+- name: ensure a wired wpasupplicant service is available
+  template:
+    src: wpa_supplicant-wired@.service.j2
+    dest: /etc/systemd/system/wpa_supplicant-wired@.service
+  notify:
+    - reload systemd service files
+    - "restart wpasupplicant@{{ ansible_default_ipv4.interface }}"
+  tags:
+    - 8021x
+
+- meta: flush_handlers
+
+- name: ensure wpasupplicant is enabled and running
+  service:
+    name: "wpa_supplicant-wired@{{ ansible_default_ipv4.interface }}"
+    state: started
+    enabled: yes
+  tags:
+    - 8021x
+
diff --git a/radius-client/templates/wpa_supplicant-wired@.service b/radius-client/templates/wpa_supplicant-wired@.service
new file mode 100644
index 0000000000000000000000000000000000000000..164cde0fa2b385a1b9326ac4d27966b68448351f
--- /dev/null
+++ b/radius-client/templates/wpa_supplicant-wired@.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=WPA supplicant daemon (interface- and wired driver-specific version)
+Requires=sys-subsystem-net-devices-%i.device
+After=sys-subsystem-net-devices-%i.device
+Before=network.target
+Wants=network.target
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-wired-%I.conf -Dwired -i%I
+
+[Install]
+Alias=multi-user.target.wants/wpa_supplicant-wired@%i.service
diff --git a/radius-client/templates/wpa_supplicant.j2 b/radius-client/templates/wpa_supplicant.j2
new file mode 100644
index 0000000000000000000000000000000000000000..ffc4de996b25ef542e5f9432391b1b0dc7f9ad5e
--- /dev/null
+++ b/radius-client/templates/wpa_supplicant.j2
@@ -0,0 +1,17 @@
+ctrl_interface=/var/run/wpa_supplicant
+
+ctrl_interface_group=0
+
+eapol_version=2
+
+ap_scan=0
+
+network={
+	key_mgmt=IEEE8021X
+	eap=TLS
+	identity="{{ inventory_hostname }}@ssl.asta.rwth-aachen.de"
+	ca_cert="/etc/ssl/certs/asta_ca.pem"
+	client_cert="/etc/wpa_supplicant/{{ inventory_hostname }}.pem"
+	private_key="/etc/wpa_supplicant/{{ inventory_hostname }}.key"
+}
+