diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json
index 697dbbcd..d53593c5 100644
--- a/client/src/__locales/en.json
+++ b/client/src/__locales/en.json
@@ -298,5 +298,14 @@
     "clients_not_found": "No clients found",
     "client_confirm_delete": "Are you sure you want to delete client \"{{key}}\"?",
     "auto_clients_title": "Clients (runtime)",
-    "auto_clients_desc": "Data on the clients that use AdGuard Home, but not stored in the configuration"
-}
\ No newline at end of file
+    "auto_clients_desc": "Data on the clients that use AdGuard Home, but not stored in the configuration",
+    "access_title": "Access settings",
+    "access_desc": "Here you can configure access rules for the AdGuard Home DNS server.",
+    "access_allowed_title": "Allowed clients",
+    "access_allowed_desc": "A list of CIDR or IP addresses. If configured, AdGuard Home will accept requests from these IP addresses only.",
+    "access_disallowed_title": "Disallowed clients",
+    "access_disallowed_desc": "A list of CIDR or IP addresses. If configured, AdGuard Home will drop requests from these IP addresses.",
+    "access_blocked_title": "Blocked domains",
+    "access_blocked_desc": "Don't confuse this with filters. AdGuard Home will drop DNS queries with these domains in query's question.",
+    "access_settings_saved": "Access settings successfully saved"
+}
diff --git a/client/src/actions/access.js b/client/src/actions/access.js
new file mode 100644
index 00000000..b10062cb
--- /dev/null
+++ b/client/src/actions/access.js
@@ -0,0 +1,45 @@
+import { createAction } from 'redux-actions';
+import Api from '../api/Api';
+import { addErrorToast, addSuccessToast } from './index';
+import { normalizeTextarea } from '../helpers/helpers';
+
+const apiClient = new Api();
+
+export const getAccessListRequest = createAction('GET_ACCESS_LIST_REQUEST');
+export const getAccessListFailure = createAction('GET_ACCESS_LIST_FAILURE');
+export const getAccessListSuccess = createAction('GET_ACCESS_LIST_SUCCESS');
+
+export const getAccessList = () => async (dispatch) => {
+    dispatch(getAccessListRequest());
+    try {
+        const data = await apiClient.getAccessList();
+        dispatch(getAccessListSuccess(data));
+    } catch (error) {
+        dispatch(addErrorToast({ error }));
+        dispatch(getAccessListFailure());
+    }
+};
+
+export const setAccessListRequest = createAction('SET_ACCESS_LIST_REQUEST');
+export const setAccessListFailure = createAction('SET_ACCESS_LIST_FAILURE');
+export const setAccessListSuccess = createAction('SET_ACCESS_LIST_SUCCESS');
+
+export const setAccessList = config => async (dispatch) => {
+    dispatch(setAccessListRequest());
+    try {
+        const { allowed_clients, disallowed_clients, blocked_hosts } = config;
+
+        const values = {
+            allowed_clients: (allowed_clients && normalizeTextarea(allowed_clients)) || [],
+            disallowed_clients: (disallowed_clients && normalizeTextarea(disallowed_clients)) || [],
+            blocked_hosts: (blocked_hosts && normalizeTextarea(blocked_hosts)) || [],
+        };
+
+        await apiClient.setAccessList(values);
+        dispatch(setAccessListSuccess());
+        dispatch(addSuccessToast('access_settings_saved'));
+    } catch (error) {
+        dispatch(addErrorToast({ error }));
+        dispatch(setAccessListFailure());
+    }
+};
diff --git a/client/src/api/Api.js b/client/src/api/Api.js
index 81bce7cf..1fa852f2 100644
--- a/client/src/api/Api.js
+++ b/client/src/api/Api.js
@@ -460,4 +460,22 @@ export default class Api {
         };
         return this.makeRequest(path, method, parameters);
     }
+
+    // DNS access settings
+    ACCESS_LIST = { path: 'access/list', method: 'GET' };
+    ACCESS_SET = { path: 'access/set', method: 'POST' };
+
+    getAccessList() {
+        const { path, method } = this.ACCESS_LIST;
+        return this.makeRequest(path, method);
+    }
+
+    setAccessList(config) {
+        const { path, method } = this.ACCESS_SET;
+        const parameters = {
+            data: config,
+            headers: { 'Content-Type': 'application/json' },
+        };
+        return this.makeRequest(path, method, parameters);
+    }
 }
diff --git a/client/src/components/Settings/Access/Form.js b/client/src/components/Settings/Access/Form.js
new file mode 100644
index 00000000..9096102d
--- /dev/null
+++ b/client/src/components/Settings/Access/Form.js
@@ -0,0 +1,80 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Field, reduxForm } from 'redux-form';
+import { Trans, withNamespaces } from 'react-i18next';
+import flow from 'lodash/flow';
+
+const Form = (props) => {
+    const { handleSubmit, submitting, invalid } = props;
+
+    return (
+        <form onSubmit={handleSubmit}>
+            <div className="form__group mb-5">
+                <label className="form__label form__label--with-desc" htmlFor="allowed_clients">
+                    <Trans>access_allowed_title</Trans>
+                </label>
+                <div className="form__desc form__desc--top">
+                    <Trans>access_allowed_desc</Trans>
+                </div>
+                <Field
+                    id="allowed_clients"
+                    name="allowed_clients"
+                    component="textarea"
+                    type="text"
+                    className="form-control form-control--textarea"
+                />
+            </div>
+            <div className="form__group mb-5">
+                <label className="form__label form__label--with-desc" htmlFor="disallowed_clients">
+                    <Trans>access_disallowed_title</Trans>
+                </label>
+                <div className="form__desc form__desc--top">
+                    <Trans>access_disallowed_desc</Trans>
+                </div>
+                <Field
+                    id="disallowed_clients"
+                    name="disallowed_clients"
+                    component="textarea"
+                    type="text"
+                    className="form-control form-control--textarea"
+                />
+            </div>
+            <div className="form__group mb-5">
+                <label className="form__label form__label--with-desc" htmlFor="blocked_hosts">
+                    <Trans>access_blocked_title</Trans>
+                </label>
+                <div className="form__desc form__desc--top">
+                    <Trans>access_blocked_desc</Trans>
+                </div>
+                <Field
+                    id="blocked_hosts"
+                    name="blocked_hosts"
+                    component="textarea"
+                    type="text"
+                    className="form-control form-control--textarea"
+                />
+            </div>
+            <div className="card-actions">
+                <div className="btn-list">
+                    <button
+                        type="submit"
+                        className="btn btn-success btn-standard"
+                        disabled={submitting || invalid}
+                    >
+                        <Trans>save_config</Trans>
+                    </button>
+                </div>
+            </div>
+        </form>
+    );
+};
+
+Form.propTypes = {
+    handleSubmit: PropTypes.func,
+    submitting: PropTypes.bool,
+    invalid: PropTypes.bool,
+    initialValues: PropTypes.object,
+    t: PropTypes.func,
+};
+
+export default flow([withNamespaces(), reduxForm({ form: 'accessForm' })])(Form);
diff --git a/client/src/components/Settings/Access/index.js b/client/src/components/Settings/Access/index.js
new file mode 100644
index 00000000..77ccc265
--- /dev/null
+++ b/client/src/components/Settings/Access/index.js
@@ -0,0 +1,43 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { withNamespaces } from 'react-i18next';
+
+import Form from './Form';
+import Card from '../../ui/Card';
+
+class Access extends Component {
+    handleFormSubmit = (values) => {
+        this.props.setAccessList(values);
+    };
+
+    render() {
+        const { t, access } = this.props;
+
+        const {
+            processing,
+            processingSet,
+            ...values
+        } = access;
+
+        return (
+            <Card
+                title={t('access_title')}
+                subtitle={t('access_desc')}
+                bodyType="card-body box-body--settings"
+            >
+                <Form
+                    initialValues={values}
+                    onSubmit={this.handleFormSubmit}
+                />
+            </Card>
+        );
+    }
+}
+
+Access.propTypes = {
+    access: PropTypes.object.isRequired,
+    setAccessList: PropTypes.func.isRequired,
+    t: PropTypes.func.isRequired,
+};
+
+export default withNamespaces()(Access);
diff --git a/client/src/components/Settings/Settings.css b/client/src/components/Settings/Settings.css
index 281330df..7e410a0c 100644
--- a/client/src/components/Settings/Settings.css
+++ b/client/src/components/Settings/Settings.css
@@ -63,6 +63,10 @@
     font-weight: 700;
 }
 
+.form__label--with-desc {
+    margin-bottom: 0;
+}
+
 .form__status {
     margin-top: 10px;
     font-size: 14px;
diff --git a/client/src/components/Settings/Upstream/Form.js b/client/src/components/Settings/Upstream/Form.js
index 8ef916f5..37990e42 100644
--- a/client/src/components/Settings/Upstream/Form.js
+++ b/client/src/components/Settings/Upstream/Form.js
@@ -62,7 +62,7 @@ let Form = (props) => {
                 </div>
                 <div className="col-12">
                     <div className="form__group">
-                        <label className="form__label" htmlFor="bootstrap_dns">
+                        <label className="form__label form__label--with-desc" htmlFor="bootstrap_dns">
                             <Trans>bootstrap_dns</Trans>
                         </label>
                         <div className="form__desc form__desc--top">
diff --git a/client/src/components/Settings/index.js b/client/src/components/Settings/index.js
index 8d36c6c4..2bafa425 100644
--- a/client/src/components/Settings/index.js
+++ b/client/src/components/Settings/index.js
@@ -7,6 +7,7 @@ import Dhcp from './Dhcp';
 import Encryption from './Encryption';
 import Clients from './Clients';
 import AutoClients from './Clients/AutoClients';
+import Access from './Access';
 import Checkbox from '../ui/Checkbox';
 import Loading from '../ui/Loading';
 import PageTitle from '../ui/PageTitle';
@@ -43,6 +44,7 @@ class Settings extends Component {
         this.props.getDhcpStatus();
         this.props.getDhcpInterfaces();
         this.props.getTlsStatus();
+        this.props.getAccessList();
     }
 
     renderSettings = (settings) => {
@@ -68,7 +70,7 @@ class Settings extends Component {
 
     render() {
         const {
-            settings, dashboard, clients, t,
+            settings, dashboard, clients, access, t,
         } = this.props;
         return (
             <Fragment>
@@ -117,6 +119,7 @@ class Settings extends Component {
                                         />
                                     </Fragment>
                                 )}
+                                <Access access={access} setAccessList={this.props.setAccessList} />
                                 <Encryption
                                     encryption={this.props.encryption}
                                     setTlsConfig={this.props.setTlsConfig}
diff --git a/client/src/containers/Settings.js b/client/src/containers/Settings.js
index 0255e044..5959d5fb 100644
--- a/client/src/containers/Settings.js
+++ b/client/src/containers/Settings.js
@@ -26,6 +26,10 @@ import {
     deleteClient,
     toggleClientModal,
 } from '../actions/clients';
+import {
+    getAccessList,
+    setAccessList,
+} from '../actions/access';
 import Settings from '../components/Settings';
 
 const mapStateToProps = (state) => {
@@ -35,6 +39,7 @@ const mapStateToProps = (state) => {
         dhcp,
         encryption,
         clients,
+        access,
     } = state;
     const props = {
         settings,
@@ -42,6 +47,7 @@ const mapStateToProps = (state) => {
         dhcp,
         encryption,
         clients,
+        access,
     };
     return props;
 };
@@ -68,6 +74,8 @@ const mapDispatchToProps = {
     addStaticLease,
     removeStaticLease,
     toggleLeaseModal,
+    getAccessList,
+    setAccessList,
 };
 
 export default connect(
diff --git a/client/src/reducers/access.js b/client/src/reducers/access.js
new file mode 100644
index 00000000..9ee258a0
--- /dev/null
+++ b/client/src/reducers/access.js
@@ -0,0 +1,43 @@
+import { handleActions } from 'redux-actions';
+
+import * as actions from '../actions/access';
+
+const access = handleActions(
+    {
+        [actions.getAccessListRequest]: state => ({ ...state, processing: true }),
+        [actions.getAccessListFailure]: state => ({ ...state, processing: false }),
+        [actions.getAccessListSuccess]: (state, { payload }) => {
+            const {
+                allowed_clients,
+                disallowed_clients,
+                blocked_hosts,
+            } = payload;
+            const newState = {
+                ...state,
+                allowed_clients: allowed_clients.join('\n'),
+                disallowed_clients: disallowed_clients.join('\n'),
+                blocked_hosts: blocked_hosts.join('\n'),
+            };
+            return newState;
+        },
+
+        [actions.setAccessListRequest]: state => ({ ...state, processingSet: true }),
+        [actions.setAccessListFailure]: state => ({ ...state, processingSet: false }),
+        [actions.setAccessListSuccess]: (state) => {
+            const newState = {
+                ...state,
+                processingSet: false,
+            };
+            return newState;
+        },
+    },
+    {
+        processing: true,
+        processingSet: false,
+        allowed_clients: null,
+        disallowed_clients: null,
+        blocked_hosts: null,
+    },
+);
+
+export default access;
diff --git a/client/src/reducers/index.js b/client/src/reducers/index.js
index e9a012f8..7e46f660 100644
--- a/client/src/reducers/index.js
+++ b/client/src/reducers/index.js
@@ -8,6 +8,7 @@ import * as actions from '../actions';
 import toasts from './toasts';
 import encryption from './encryption';
 import clients from './clients';
+import access from './access';
 
 const settings = handleActions({
     [actions.initSettingsRequest]: state => ({ ...state, processing: true }),
@@ -418,6 +419,7 @@ export default combineReducers({
     dhcp,
     encryption,
     clients,
+    access,
     loadingBar: loadingBarReducer,
     form: formReducer,
 });