Host Your Own Virtual Private Network (VPN) with OpenVPN
A Virtual Private Network, or VPN, creates an encrypted tunnel between you computer (client) and the VPN (server). This encrypted tunnel carries data that cannot be deciphered without the proper keys, and you control what clients have access to those keys. A popular VPN software is called OpenVPN. This software uses strong encryption methods to help ensure that no spying eyes can see what you are doing. I cannot guarantee that this software will keep you completely anonymous, but it is an excellent start. VPNs have many other uses besides Internet anonymity; they can connect a user to a local area network even if they are not anywhere near it. If you need to access a file at a business from your home, a VPN is probably used. The objective of this guide is to explain how to configure OpenVPN on a server and client to form a strong encrypted VPN tunnel.
This guide helped me configure my connection. If you run into any trouble in this tutorial, take a look at this guide or leave a comment below.
This guide helped me configure my connection. If you run into any trouble in this tutorial, take a look at this guide or leave a comment below.
Step 1: Prerequisites
These are the things you will need in order to successfully create a VPN.
An Ubuntu Linux Server. If you do not have a Linux Server, refer to my cloud guide for more information on how to set one up.
Port forwarding skills. If you do not know how to port forward on a router, check out Step 7 of my cloud guide for specific instructions.
A domain name attached to your server. If you do not have a domain name for your server, refer to Step 9 of the cloud guide for instructions. If you have not already noticed, my cloud guide is a great reference point for basic information regarding server setup. I walk though the entire server setup in that guide. Please do not hesitate to ask questions! It is very important that you follow this guide to the letter. One mis-configured setting can throw off the entire configuration.
An Ubuntu Linux Server. If you do not have a Linux Server, refer to my cloud guide for more information on how to set one up.
Port forwarding skills. If you do not know how to port forward on a router, check out Step 7 of my cloud guide for specific instructions.
A domain name attached to your server. If you do not have a domain name for your server, refer to Step 9 of the cloud guide for instructions. If you have not already noticed, my cloud guide is a great reference point for basic information regarding server setup. I walk though the entire server setup in that guide. Please do not hesitate to ask questions! It is very important that you follow this guide to the letter. One mis-configured setting can throw off the entire configuration.
Step 2: Install OpenVPN
We need to install OpenVPN on the Ubuntu Server in order to configure it properly. Open a terminal by pressing Control + Alt + T. Once the terminal window is open type:
sudo apt-get install openvpn bridge-utils
This will install the openvpn client on our server.
Note Ubuntu will ask your password. Type in the password that you created when you installed Ubuntu on the system. Do not worry that no asterisks are showing up when you are typing your password, its supposed to work that way!
sudo apt-get install openvpn bridge-utils
This will install the openvpn client on our server.
Note Ubuntu will ask your password. Type in the password that you created when you installed Ubuntu on the system. Do not worry that no asterisks are showing up when you are typing your password, its supposed to work that way!
Step 3: Configure Network Settings
We need to create a bridge in our server to allow the VPN to work. Open a terminal and type:
sudo nano /etc/network/interfaces
This command will allow you to edit the interfaces file of the server. The file should have two lines in it. If your file has more lines in it, be sure to comment those out with a hashtag (#). I have added my comments in the example file below. Please remember to change the fields according to your specific network requirements. Make sure that you do not copy the first two lines of this code if you already have them in your file. Copy and paste the following code into the file. Once you have finished, press Control + O and Enter to save changes, and then Control + X to exit.
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
# The next two lines are the original lines of the file, leave them in here.
auto lo
iface lo inet loopback
#These next lines will create a the bridge for OpenVPN
auto br0
iface br0 inet static
address 192.168.2.50
#The IP Address above needs to be the IP address of your server.
#Be sure that this IP address is the Internal IP Address of the
#Server, not the public IP. It should look similair to the IP
#Address above.
netmask 255.255.255.0
#The netmask will probably not need to be changed.
gateway 192.168.101.1
#The gateway column refers to the default gateaway of your router.
#This address will probably be the same as the address used to
#port forward.
bridge_ports eth0
#This command bridges your ethernet connection for OpenVPN
iface eth0 inet manual
up ifconfig $IFACE 0.0.0.0 up
up ip link set $IFACE promisc on
down ip link set $IFACE promisc off
down ifconfig $IFACE down
#I really don't know what these last set of lines do, but they
#still need to be here.
sudo nano /etc/network/interfaces
This command will allow you to edit the interfaces file of the server. The file should have two lines in it. If your file has more lines in it, be sure to comment those out with a hashtag (#). I have added my comments in the example file below. Please remember to change the fields according to your specific network requirements. Make sure that you do not copy the first two lines of this code if you already have them in your file. Copy and paste the following code into the file. Once you have finished, press Control + O and Enter to save changes, and then Control + X to exit.
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
# The next two lines are the original lines of the file, leave them in here.
auto lo
iface lo inet loopback
#These next lines will create a the bridge for OpenVPN
auto br0
iface br0 inet static
address 192.168.2.50
#The IP Address above needs to be the IP address of your server.
#Be sure that this IP address is the Internal IP Address of the
#Server, not the public IP. It should look similair to the IP
#Address above.
netmask 255.255.255.0
#The netmask will probably not need to be changed.
gateway 192.168.101.1
#The gateway column refers to the default gateaway of your router.
#This address will probably be the same as the address used to
#port forward.
bridge_ports eth0
#This command bridges your ethernet connection for OpenVPN
iface eth0 inet manual
up ifconfig $IFACE 0.0.0.0 up
up ip link set $IFACE promisc on
down ip link set $IFACE promisc off
down ifconfig $IFACE down
#I really don't know what these last set of lines do, but they
#still need to be here.
Step 4: More Configuration and Forwarding!
We need to enable IPv4 forwarding so a client on the VPN can browse the Internet. In the terminal type:
sudo nano /etc/sysctl.conf
Uncomment the line that says net.ipv4.ip_forward=1. To uncomment a line, simply remove the hashtag (#) at the beginning of the line.
Next, we need to forward port 1194 to the IP address of our server. Please seeStep 7 of my cloud guide for more information on how to port forward.
Reboot your server and ensure that all networking components are working. To test this, try to ping the server's IP address from another client on the network. If you are using windows, open a command prompt and type:
ping <your server's IP address>
If you get a response, you are good to go!
sudo nano /etc/sysctl.conf
Uncomment the line that says net.ipv4.ip_forward=1. To uncomment a line, simply remove the hashtag (#) at the beginning of the line.
Next, we need to forward port 1194 to the IP address of our server. Please seeStep 7 of my cloud guide for more information on how to port forward.
Reboot your server and ensure that all networking components are working. To test this, try to ping the server's IP address from another client on the network. If you are using windows, open a command prompt and type:
ping <your server's IP address>
If you get a response, you are good to go!
Step 5: Create the Server Keys and Certificates
The certificates we will create in this step allow our server to authorize clients trying to access the VPN.
Housekeeping
First we need to make an Easy-rsa folder, Open a terminal on the server and type:
sudo mkdir /etc/openvpn/easy-rsa/
Next, we need the example certificate files from one directory to the directory we just created. In the terminal, enter:
sudo cp -R /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa/
Change the ownership of the files by using the chown command. In the terminal enter:
sudo chown -R $USER /etc/openvpn/easy-rsa/
Vars file
We need to make some changes to the vars file in order to properly generate our certificates. In the terminal type:
sudo nano /etc/openvpn/easy-rsa/vars
This command will open the vars file in the terminal, we need to edit a couple of fields. The first field we need to edit is the export KEY_CONFIG field. Look for that line in the file and replace it with:
export KEY_CONFIG=/etc/openvpn/easy-rsa/openssl-0.9.6.cnf
This is the configuration file used to create authorization certificates.
Next, change the following fields at the bottom of your file to you liking. There are two e-mail lines, but you only need to edit the first one. Make sure you have quotation marks around each of the values.
export KEY_COUNTRY
export KEY_PROVINCE
export KEY_CITY
export KEY_ORG
export KEY_EMAIL
Once you are finished editing the values, press Control + O and then enter to save the changes, and Control + X to exit back into terminal.
We are now ready to generate certificates for the server.
This next set of scripts is going to create the script for the server and one client. In terminal, use the cd command to move into the proper directory by entering:
cd /etc/openvpn/easy-rsa/
Open the source script:
source vars
Clean the directory:
./clean-all
Build the encryption of the certificates and build the actual certificates:
./build-dh
./pkitool --initca
./pkitool --server server
Move into the new keys directory:
cd keys
Generate another key:
openvpn --genkey --secret ta.key
Copy all the keys into the /etc/openvpn/ directory:
sudo cp server.crt server.key ca.crt dh1024.pem ta.key /etc/openvpn/
The server keys and certificates are now created. Next, we need to make the client keys and certificates.
Housekeeping
First we need to make an Easy-rsa folder, Open a terminal on the server and type:
sudo mkdir /etc/openvpn/easy-rsa/
Next, we need the example certificate files from one directory to the directory we just created. In the terminal, enter:
sudo cp -R /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa/
Change the ownership of the files by using the chown command. In the terminal enter:
sudo chown -R $USER /etc/openvpn/easy-rsa/
Vars file
We need to make some changes to the vars file in order to properly generate our certificates. In the terminal type:
sudo nano /etc/openvpn/easy-rsa/vars
This command will open the vars file in the terminal, we need to edit a couple of fields. The first field we need to edit is the export KEY_CONFIG field. Look for that line in the file and replace it with:
export KEY_CONFIG=/etc/openvpn/easy-rsa/openssl-0.9.6.cnf
This is the configuration file used to create authorization certificates.
Next, change the following fields at the bottom of your file to you liking. There are two e-mail lines, but you only need to edit the first one. Make sure you have quotation marks around each of the values.
export KEY_COUNTRY
export KEY_PROVINCE
export KEY_CITY
export KEY_ORG
export KEY_EMAIL
Once you are finished editing the values, press Control + O and then enter to save the changes, and Control + X to exit back into terminal.
We are now ready to generate certificates for the server.
This next set of scripts is going to create the script for the server and one client. In terminal, use the cd command to move into the proper directory by entering:
cd /etc/openvpn/easy-rsa/
Open the source script:
source vars
Clean the directory:
./clean-all
Build the encryption of the certificates and build the actual certificates:
./build-dh
./pkitool --initca
./pkitool --server server
Move into the new keys directory:
cd keys
Generate another key:
openvpn --genkey --secret ta.key
Copy all the keys into the /etc/openvpn/ directory:
sudo cp server.crt server.key ca.crt dh1024.pem ta.key /etc/openvpn/
The server keys and certificates are now created. Next, we need to make the client keys and certificates.
Step 6: Create Client Certificates
The client certificates allow a client device access to the VPN server. These certificates will be made on the server and transferred to the client PC. Open a terminal and enter:
cd /etc/openvpn/easy-rsa/
Then prepare the vars script:
source vars
Create the client certificates:
KEY_CN=client ./pkitool client
Replace the word client with whatever name you are assigning to the client device. In my example, I assign the name ubuntu to my client device. Be sure to change both instances of the word client to your specific client name.
Transfer the following files from the server to the client device. If Ubuntu does not let you copy the files. Try pressing Alt+f2 and entering gksudo +nautilus. Then you will be copying the files as root.
/etc/openvpn/ca.crt
/etc/openvpn/ta.key
/etc/openvpn/easy-rsa/keys/client.crt
/etc/openvpn/easy-rsa/keys/client.key
Please note that the first two files have different directories than the last two. Transfer the files to the client device using some form of physical storage. Do not transfer the files over the Internet in a non-secure fashion such as e-mailing them to yourself. Later in this Instructable, I will show you where to place those files on the client device.
cd /etc/openvpn/easy-rsa/
Then prepare the vars script:
source vars
Create the client certificates:
KEY_CN=client ./pkitool client
Replace the word client with whatever name you are assigning to the client device. In my example, I assign the name ubuntu to my client device. Be sure to change both instances of the word client to your specific client name.
Transfer the following files from the server to the client device. If Ubuntu does not let you copy the files. Try pressing Alt+f2 and entering gksudo +nautilus. Then you will be copying the files as root.
/etc/openvpn/ca.crt
/etc/openvpn/ta.key
/etc/openvpn/easy-rsa/keys/client.crt
/etc/openvpn/easy-rsa/keys/client.key
Please note that the first two files have different directories than the last two. Transfer the files to the client device using some form of physical storage. Do not transfer the files over the Internet in a non-secure fashion such as e-mailing them to yourself. Later in this Instructable, I will show you where to place those files on the client device.
Step 7: Create Server VPN Scripts
The server needs some VPN Scripts bring up the VPN network, and to bring the VPN network back down. In a terminal on the server, create the 'up' script by entering:
sudo nano /etc/openvpn/up.sh
A blank document will open in the temrinal. Copy and paste this text into the document:
#!/bin/sh
BR=$1
DEV=$2
MTU=$3
/sbin/ifconfig $DEV mtu $MTU promisc up
/sbin/brctl addif $BR $DEV
Once finished press Control + O to save changes and Control + X to exit. Now we need to create the 'down' script. In the same terminal enter:
sudo nano /etc/openvpn/down.sh
A blank document will open in the temrinal. Copy and paste this text into the document:
#!/bin/sh
BR=$1
DEV=$2
/sbin/brctl delif $BR $DEV
/sbin/ifconfig $DEV down
Once finished press Control + O to save changes and Control + X to exit.
Finally we need to make the scripts executable. In terminal, enter:
sudo chmod 755 /etc/openvpn/down.sh
and
sudo chmod 755 /etc/openvpn/up.sh
This completes the up and down scripts for OpenVPN
sudo nano /etc/openvpn/up.sh
A blank document will open in the temrinal. Copy and paste this text into the document:
#!/bin/sh
BR=$1
DEV=$2
MTU=$3
/sbin/ifconfig $DEV mtu $MTU promisc up
/sbin/brctl addif $BR $DEV
Once finished press Control + O to save changes and Control + X to exit. Now we need to create the 'down' script. In the same terminal enter:
sudo nano /etc/openvpn/down.sh
A blank document will open in the temrinal. Copy and paste this text into the document:
#!/bin/sh
BR=$1
DEV=$2
/sbin/brctl delif $BR $DEV
/sbin/ifconfig $DEV down
Once finished press Control + O to save changes and Control + X to exit.
Finally we need to make the scripts executable. In terminal, enter:
sudo chmod 755 /etc/openvpn/down.sh
and
sudo chmod 755 /etc/openvpn/up.sh
This completes the up and down scripts for OpenVPN
Step 8: Configure OpenVPN Settings
This is a very confusing part for most people, so this is a very important step. We are going to configure the proper settings for the VPN server. There are many different things we have to change in this configuration file. In the file, a semicolon at the beginning of a line means that the line is commented out, meaning it does not apply. To uncomment a line, simply remove the semicolon and the line will become active. I will demonstrate this with as many pictures as I can. Please look at those pictures for the proper configurations if you do not understand the text. I am just going to tell you what to do in the text, so the pictures are extremely important.
Copy the sample configuration files to our openVPN server directory. In a terminal enter:
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz
Then, open the Configuration file. In a terminal enter:
sudo nano /etc/openvpn/server.conf
Make these changes in the file:
Comment out the dev tun line.
Uncomment the dev tap line and add a 0 to the end. It should now say 'dev tap0'
Comment out server 10.8.0.0 255.255.255.0
Uncomment the ;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 line.
Change that line to something like: server-bridge 192.168.101.50 255.255.255.0 192.168.101.85
192.168.101.99
The first IP address is the local address of the server. The second set of numbers is the subnet mask, match it to your IP address. In most cases this value will not need to be changed, The third set of numbers is the beginning range IP address you would like to assign to devices that connect to your VPN. The fourth set of numbers is the ending range IP address you assign to client VPN devices. When a device connects to the VPN, it will be assigned a local IP address defined in the final two sets of numbers in this line. It is important that you do not assign IP addresses in this file that are already in use by other devices on the local network.
Uncomment the ;push "route 192.168.101.1 255.255.255.0" line.
Change the IP address to match that of your default gateway. In my example it is: 192.168.2.1.
Uncomment the ;push "redirect-gateway def1 bypass-dhcp" line.
Uncomment the ;push "dhcp-option DNS 208.67.222.222" and ;push "dhcp-option DNS 208.67.220.220" lines. If you would like to point the point the server to your own DNS servers, change the DNS server IP addresses. If not, you can leave this addresses alone as they are OpenVPN's DNS Servers.
Uncomment the ;tls-auth ta.key 0 # This file is secret line.
Uncomment the ;cipher AES-128-CBC line.
Uncomment the ;user nobody and ;group nogroup lines
Add these next three lines to the bottom of the file:
up "/etc/openvpn/up.sh br0"
down "/etc/openvpn/down.sh br0"
push "explicit-exit-notify 3"
Reboot your server to restart all networking equipment.
This completes the VPN server configuration, now we need to configure our client.
Copy the sample configuration files to our openVPN server directory. In a terminal enter:
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz
Then, open the Configuration file. In a terminal enter:
sudo nano /etc/openvpn/server.conf
Make these changes in the file:
Comment out the dev tun line.
Uncomment the dev tap line and add a 0 to the end. It should now say 'dev tap0'
Comment out server 10.8.0.0 255.255.255.0
Uncomment the ;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 line.
Change that line to something like: server-bridge 192.168.101.50 255.255.255.0 192.168.101.85
192.168.101.99
The first IP address is the local address of the server. The second set of numbers is the subnet mask, match it to your IP address. In most cases this value will not need to be changed, The third set of numbers is the beginning range IP address you would like to assign to devices that connect to your VPN. The fourth set of numbers is the ending range IP address you assign to client VPN devices. When a device connects to the VPN, it will be assigned a local IP address defined in the final two sets of numbers in this line. It is important that you do not assign IP addresses in this file that are already in use by other devices on the local network.
Uncomment the ;push "route 192.168.101.1 255.255.255.0" line.
Change the IP address to match that of your default gateway. In my example it is: 192.168.2.1.
Uncomment the ;push "redirect-gateway def1 bypass-dhcp" line.
Uncomment the ;push "dhcp-option DNS 208.67.222.222" and ;push "dhcp-option DNS 208.67.220.220" lines. If you would like to point the point the server to your own DNS servers, change the DNS server IP addresses. If not, you can leave this addresses alone as they are OpenVPN's DNS Servers.
Uncomment the ;tls-auth ta.key 0 # This file is secret line.
Uncomment the ;cipher AES-128-CBC line.
Uncomment the ;user nobody and ;group nogroup lines
Add these next three lines to the bottom of the file:
up "/etc/openvpn/up.sh br0"
down "/etc/openvpn/down.sh br0"
push "explicit-exit-notify 3"
Reboot your server to restart all networking equipment.
This completes the VPN server configuration, now we need to configure our client.
Step 9: Install and Configure OpenVPN on Ubuntu Linux
This step will explain how to install and configure the OpenVPN client on Ubuntu Linux. If you are using Windows, I have created a configuration guide in the next step. I would head over there now.
In a terminal on the client device enter:
sudo apt-get install network-manager-openvpn-gnome
Copy the certificates from Step 6 into the home directory.
Open the network manager by clicking System Settings > Network.
Press the + button at the bottom of the page and create a VPN Interface. Choose OpenVPN as the connection type and click Create.
Name your VPN in the Connection Name field.
Enter the server's domain name you registered earlier in the gateway field.
Open your client.crt file in the user certificate field.
Open the ca.crt file in the CA Certificate field.
Open the client.key file in the Private Key field.
Click Advanced
In the general tab:
Check the Use LZO Data Compression checkbox
Check the Use a TAP device checkbox
In the security tab:
From the drop-down list in the cipher field, select AES-128-CBC.
In the TLS Authentication tab:
Check the Use additional TLS authentication checkbox.
Open the ta.key file from your home directory
Set the key direction to 1
Click Ok to save the Advanced Settings.
In the general tab:
Uncheck the All users may connect to this network checkbox.
Click Save to save your VPN settings.
Turn the VPN connection on and you should be good to connect to your VPN.
In a terminal on the client device enter:
sudo apt-get install network-manager-openvpn-gnome
Copy the certificates from Step 6 into the home directory.
Open the network manager by clicking System Settings > Network.
Press the + button at the bottom of the page and create a VPN Interface. Choose OpenVPN as the connection type and click Create.
Name your VPN in the Connection Name field.
Enter the server's domain name you registered earlier in the gateway field.
Open your client.crt file in the user certificate field.
Open the ca.crt file in the CA Certificate field.
Open the client.key file in the Private Key field.
Click Advanced
In the general tab:
Check the Use LZO Data Compression checkbox
Check the Use a TAP device checkbox
In the security tab:
From the drop-down list in the cipher field, select AES-128-CBC.
In the TLS Authentication tab:
Check the Use additional TLS authentication checkbox.
Open the ta.key file from your home directory
Set the key direction to 1
Click Ok to save the Advanced Settings.
In the general tab:
Uncheck the All users may connect to this network checkbox.
Click Save to save your VPN settings.
Turn the VPN connection on and you should be good to connect to your VPN.
Step 10: Install and Configure OpenVPN on Windows
Now I will show the Windows users how to configure OpenVPN on the client PC. First, visit this link and download the OpenVPN client for your version of Windows.
Next, open My Computer and click on your C: drive. Navigate to Program Files> OpenVPN>sample-config. If you are using Windows Vista/7/8, open My Computer as administrator.
Copy the client file.
Go back one directory and click the config folder. Paste the client file in this directory. Also, paste the files you copied from the server earlier in this guide into this folder.
Open the client.ovpn file with notepad. Edit the following lines just like in the server.conf file.
Comment out the dev tun line
Uncomment the dev tap line and add a 0 to the end. The line should now say 'dev tap0'.
In the remote server line, enter the domain name of your server. Do not remove the remote word or the 1194. See the picture for clarification.
In the SSL/TLS section. Enter the names of your keys and certificates. In my example I enter:
ca.crt
client.crt
client.key
Please see my picture for further clarification on this step.
Uncomment the tls-auth ta.key 1 line.
Uncomment the cipher line and replace the x with AES-128-CBC. The line should now look like 'cipher AES-128-CBC'
Save the client file.
There should be a OpenVPN GUI icon on your desktop. Open this program. If you are using Windows Vista/7/8 open this program as administrator. The program will load the configuration file. To connect to your VPN, find the icon in the system tray. Right click it and click connect. The program should now connect you to your VPN server.
Next, open My Computer and click on your C: drive. Navigate to Program Files> OpenVPN>sample-config. If you are using Windows Vista/7/8, open My Computer as administrator.
Copy the client file.
Go back one directory and click the config folder. Paste the client file in this directory. Also, paste the files you copied from the server earlier in this guide into this folder.
Open the client.ovpn file with notepad. Edit the following lines just like in the server.conf file.
Comment out the dev tun line
Uncomment the dev tap line and add a 0 to the end. The line should now say 'dev tap0'.
In the remote server line, enter the domain name of your server. Do not remove the remote word or the 1194. See the picture for clarification.
In the SSL/TLS section. Enter the names of your keys and certificates. In my example I enter:
ca.crt
client.crt
client.key
Please see my picture for further clarification on this step.
Uncomment the tls-auth ta.key 1 line.
Uncomment the cipher line and replace the x with AES-128-CBC. The line should now look like 'cipher AES-128-CBC'
Save the client file.
There should be a OpenVPN GUI icon on your desktop. Open this program. If you are using Windows Vista/7/8 open this program as administrator. The program will load the configuration file. To connect to your VPN, find the icon in the system tray. Right click it and click connect. The program should now connect you to your VPN server.
Your assistance is greatly appreciated.
So, change the command to:
sudo apt-get install easy-rsa
chmod 700 ta.key
chmod 700 client1.key
chmod 700 client1.crt
chmod 700 ca.crt
Using ubuntu server 14.04.
Cheers fom Brazil.
The server isn't connected to the router in the background, as it's not showing up on my "Connected Devices" list. If I remove the lines of code from the interfaces file, connectivity is restored.
Any further help you can offer would be fantastic!