Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
401 updates
wgthom committed Jun 6, 2019
1 parent 604dde4 commit 686644c
Showing 14 changed files with 209 additions and 147 deletions.
185 changes: 137 additions & 48 deletions docs/401/401.1.rst
@@ -156,7 +156,7 @@ contractors, etc.)"
#. Compare counts between `vpn_legacy` and `vpn_authorized`.
`vpn_authorized`. Why are they different?


----------------------------------------------------
Exercise 401.1.3 Export `vpn_authorized` to OpenLDAP
----------------------------------------------------
@@ -220,7 +220,8 @@ group.
delegated to a professor.
#. Add each of these ACLs to `vpn_adhoc`


.. figure:: ../figures/401-vpn-acls-visual.png

+++++++++++++++++++++++++++++++++++
Professor Johnson's Special Project
+++++++++++++++++++++++++++++++++++
@@ -252,72 +253,160 @@ we must create a security group and grant it appropriate permissions:

.. figure:: ../figures/401-bsmith458-trace.png

""""""""""""""""""""""
Put Limits on Policies
""""""""""""""""""""""
--------------------------------------------------------
Exercise 401.1.5 Implement additional policy constraints
--------------------------------------------------------

It is the IAM team's responsibility to make sure that VPN access is granted to
the correct subjects. Putting some limits in place can help make sure improper
access is not granted. Attestation makes sure that access which was granted in
the correct subjects. Putting some limits in place can help make sure improper
access is not granted. Attestation makes sure that access which was granted in
the past is still appropriate.

#. Create `ref:iam:global_deny`. This reference group represents a broad cohort
of subjects that should not be granted access to most policies. Subjects
that fall into this category may be:
#. The `ref:iam:global_deny` reference group represents a broad cohort
of subjects that should not be granted access. Subjects that fall into
this category may include:

* Termed "with cause"
* Termed with cause
* Deceased
* Other reasons

#. Add `ref:iam:global_deny` to the `app:vpn:vpn_deny` policy.
#. Add attestation requirements to the `app:vpn:ref:vpn_ajohnson409` ACL.
#. Add `ref:iam:global_deny` to the `vpn_authorized_deny` policy group.

* Create attestation requirements (30 days).
* Review notification settings.
* View :guilabel:`home` -> :guilabel:`misc` -> :guilabel:`attestation settings`.
* Log in as `ajohnson409` and attest!
* View audit log to see who attested group.
#. Add 30 day attestation requirements to the `vpn_ajohnson409` ACL.
(vpn_ajohnson409 -> More actions -> Attestation -> Attestion actions ->
Edit attestion settings...)

#. Add automatic age-off / lifecycle - exceptions only good for 180 days.
There are 2 techniques:
.. figure:: ../figures/401-vpn-attest.png

* Add member, edit membership, add membership end date.
* Better approach, use grouper rule to automatically add end date to
members. See :ref:`the appendix <apdx-401.1.4-auto-end-date>` for
details.
#. Review attestations (Miscellaneous -> Attestation)

#. Use Grouper 2.4 affiliation-based deprovisioning.
.. figure:: ../figures/401-vpn-misc-attest.png

All access to VPN is now traceable to natural language policy and known
exceptions! Policy is enforced automatically and kept in sync with changing
subject attributes. Exceptions are known and managed with a defined
attestation lifecycle. VPN policy participates in the global deny policy.
Consultant exceptions should expire automatically after 180 days. There are 2
techniques to accomplish this in Grouper. The first is to simply edit the
membership end date after you have added a subject to a group. The second, and
more reliable, is to have a rule that runs every time a subject is added which
autotmatically sets the membership end date. Let's implement the second
approach.

----------------
Exercise 401.1.5
----------------
#. Run `./gte-shell 401.1.1` to get a command prompt.

*CISO is working on a investigation and wants to know if this particular NetID
"blee172" has access to the VPN now or in the past 90 days?*
#. Run `./bin/gsh` to start the Grouper shell

#. Navigate to `apps:vpn:vpn_authorized`.
#. Search for so-and-so.
#. Open up phpMyAdmin (https://localhost:8443/phpmyadmin/)
#. Open Views, Go to SQL tab, paste in
:ref:`PIT query <apdx-401.1.5-pit-query>`, Go!
#. Paste in the following gsh script:

.. code-block:: groovy
.. _apdx-401.1.5-pit-query:
// Automatically expire vpn_consultant subject memberships in 180 days
gs = GrouperSession.startRootSession();
numberOfDays = 180;
actAs = SubjectFinder.findRootSubject();
vpn_consultants = GroupFinder.findByName(gs, "app:vpn:service:ref:vpn_consultants");
attribAssign = vpn_consultants.getAttributeDelegate().addAttribute(RuleUtils.ruleAttributeDefName()).getAttributeAssign();
attribValueDelegate = attribAssign.getAttributeValueDelegate();
attribValueDelegate.assignValue(RuleUtils.ruleActAsSubjectSourceIdName(), actAs.getSourceId());
attribValueDelegate.assignValue(RuleUtils.ruleActAsSubjectIdName(), actAs.getId());
attribValueDelegate.assignValue(RuleUtils.ruleCheckTypeName(), RuleCheckType.membershipAdd.name());
attribValueDelegate.assignValue(RuleUtils.ruleThenEnumName(), RuleThenEnum.assignMembershipDisabledDaysForOwnerGroupId.name());
attribValueDelegate.assignValue(RuleUtils.ruleThenEnumArg0Name(), numberOfDays.toString());
attribValueDelegate.assignValue(RuleUtils.ruleThenEnumArg1Name(), "T");
----------------
Exercise 401.1.6
----------------
#. Add `jsmith` to `vpn_consultants` and then review the membership end date.
(vpn_consultants -> jsmith -> Edit membership and privileges)

*CISO wants to know if anyone on this list of NetIDs has access to the VPN? And
why?*
.. figure:: ../figures/401-vpn-add-jsmith.png

#. Import list to a test group.
#. Intersect with `vpn_authorized`.
#. Trace membership to determine what level of access and why.
.. figure:: ../figures/401-vpn-jsmith-end-date.png

---------------------------------------------------
Exercise 401.1.5 Does "blee172" have access to VPN?
---------------------------------------------------

The CISO is working on a investigation and wants to know if this particular
NetID "blee172" has access to the VPN now or in the past 90 days?

#. Navigate to `apps:vpn:vpn_authorized`.
#. Search for `blee172` and trace membership.

.. figure:: ../figures/401-vpn-trace-blee172.png

Betty currently has access since she is staff.
The Point-In-Time (PIT) tables know if she's had access in the last 90 days.

3. Log in to phpMyAdmin (https://localhost:8443/phpmyadmin/) with username
`root` and a blank password.

4. In the database explore, open grouper Views, then go to SQL tab, paste in
the following block:

.. code-block:: SQL
SELECT
gpm.SUBJECT_ID,
gpg.NAME,
FROM_UNIXTIME(gpmav.MEMBERSHIP_START_TIME / 1000000) start_time,
FROM_UNIXTIME(gpmav.MEMBERSHIP_END_TIME / 1000000) end_time
FROM grouper_pit_memberships_all_v gpmav
INNER JOIN grouper_pit_groups gpg
ON gpmav.owner_group_id = gpg.id
INNER JOIN grouper_pit_members gpm
ON gpmav.MEMBER_ID = gpm.id
INNER JOIN grouper_pit_fields gpf
ON gpmav.field_id = gpf.id
WHERE gpg.name = 'app:vpn:service:policy:vpn_authorized'
AND gpm.subject_type = 'person'
AND gpf.name = 'members'
ORDER BY gpmav.MEMBERSHIP_START_TIME DESC
;
5. Filter rows for `blee172`. This shows Betty's earliest access was
2019-06-03.

.. figure:: ../figures/401-vpn-blee172-pit-query.png

---------------------------------------------------
Exercise 401.1.6 VPN access audit or list of NetIDs
---------------------------------------------------

CISO wants to know if anyone on this list of NetIDs has access to the VPN? And
why?

1. Import the following list to `test:vpn:vpn_audit_list`

.. code-block::
ahenderson36
cpeterson37
jclark39
kbrown62
tpeterson63
pjohnson64
aroberts95
sdavis107
mhenderson109
jvales117
sgrady139
mprice142
mwilliams144
lpeterson153
mvales154
bsmith458
2. Create `test:vpn:vpn_audit`

3. Edit composite on `vpn_audit` and create an interection of `vpn_authorized`
and `vpn_audit_list`. This will tell us who in `vpn_audit_list` is also in
`vpn_authorized`.

#. Review and trace membership to determine why they have access.

.. figure:: ../figures/401-vpn-audit-list.png

Congrats! All access to VPN is now traceable to natural language policy and
known exceptions! Policy is enforced automatically and kept in sync with
changing subject attributes. Exceptions are known and managed with a defined
attestation lifecycle. Exception managment is distributed and VPN policy
participates in the global deny policy.

.. _Grouper Deployment Guide: https://spaces.at.internet2.edu/display/Grouper/Grouper+Deployment+Guide+Work+-TIER+Program
.. _`PSPNG`: https://spaces.at.internet2.edu/x/iwfSBQ
65 changes: 0 additions & 65 deletions docs/401/appendix.rst
@@ -2,71 +2,6 @@
Appendix
========

.. _apdx-401.1.4-auto-end-date:

-------------------------------
401.1.4 Automatic End Date Rule
-------------------------------

To configure the automatic rule end date on the access control list,
`app:vpn:ref:vpn_adhoc` you must use the Grouper Shell (GSH) to run
a short script. To run GSH, you must connect to the GTE container
that has the Grouper API installed:

.. code-block:: bash
root# docker exec -it CONTAINER_NAME /bin/bash
bash# cd bin
bash# gsh
At this point you can paste in the following script:

.. code-block:: groovy
:emphasize-lines: 1,3
:linenos:
numDays = 180;
actAs = SubjectFinder.findRootSubject();
vpn_adhoc = getGroups("app:vpn:ref:vpn_adhoc")[0];
attribAssign = vpn_adhoc.getAttributeDelegate().addAttribute(RuleUtils.ruleAttributeDefName()).getAttributeAssign();
attribValueDelegate = attribAssign.getAttributeValueDelegate();
attribValueDelegate.assignValue(RuleUtils.ruleActAsSubjectSourceIdName(), actAs.getSourceId());
attribValueDelegate.assignValue(RuleUtils.ruleRunDaemonName(), "F");
attribValueDelegate.assignValue(RuleUtils.ruleActAsSubjectIdName(), actAs.getId());
attribValueDelegate.assignValue(RuleUtils.ruleCheckTypeName(), RuleCheckType.membershipAdd.name());
attribValueDelegate.assignValue(RuleUtils.ruleIfConditionEnumName(), RuleIfConditionEnum.thisGroupHasImmediateEnabledNoEndDateMembership.name());
attribValueDelegate.assignValue(RuleUtils.ruleThenEnumName(), RuleThenEnum.assignMembershipDisabledDaysForOwnerGroupId.name());
attribValueDelegate.assignValue(RuleUtils.ruleThenEnumArg0Name(), numDays.toString());
attribValueDelegate.assignValue(RuleUtils.ruleThenEnumArg1Name(), "T");
.. _apdx-401.1.5-pit-query:

--------------------------------------
401.1.5 Point-in-Time Membership Query
--------------------------------------

.. code-block:: sql
:linenos:
SELECT
gpm.SUBJECT_ID,
gpg.NAME,
FROM_UNIXTIME(gpmav.MEMBERSHIP_START_TIME / 1000000) start_time,
FROM_UNIXTIME(gpmav.MEMBERSHIP_END_TIME / 1000000) end_time
FROM grouper_pit_memberships_all_v gpmav
INNER JOIN grouper_pit_groups gpg
ON gpmav.owner_group_id = gpg.id
INNER JOIN grouper_pit_members gpm
ON gpmav.MEMBER_ID = gpm.id
INNER JOIN grouper_pit_fields gpf
ON gpmav.field_id = gpf.id
WHERE gpg.name = 'app:vpn:vpn_authorized'
AND gpm.subject_type = 'person'
AND gpf.name = 'members'
ORDER BY gpmav.MEMBERSHIP_START_TIME DESC
;
.. _apdx-401.2.5-future-memberships-query:

--------------------------------
Binary file added docs/figures/401-vpn-acls-visual.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/figures/401-vpn-add-jsmith.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/figures/401-vpn-attest.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/figures/401-vpn-audit-list.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/figures/401-vpn-blee172-pit-query.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/figures/401-vpn-misc-attest.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/figures/401-vpn-trace-blee172.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions ex401/class-files/CisoQuestionalUsers.txt
@@ -13,3 +13,4 @@ mprice142
mwilliams144
lpeterson153
mvales154
bsmith458
7 changes: 3 additions & 4 deletions ex401/ex401.1.1/container_files/seed-data/bootstrap.gsh
@@ -6,8 +6,7 @@ addRootStem("app", "app");
addRootStem("org", "org");
addRootStem("test", "test");

//delStem("401.1.end")
addRootStem("401.4.1", "401.4.1")
addRootStem("401.1.1", "401.1.1")

addStem("ref", "iam", "iam");
addGroup("ref:iam", "global_deny", "global_deny");
@@ -19,7 +18,7 @@ setGroupAttr("etc:rolesLoader", "grouperLoaderType", "SQL_GROUP_LIST");
setGroupAttr("etc:rolesLoader", "grouperLoaderScheduleType", "CRON");
setGroupAttr("etc:rolesLoader", "grouperLoaderQuartzCron", "0 * * * * ?");
setGroupAttr("etc:rolesLoader", "grouperLoaderQuery", "select distinct id as SUBJECT_IDENTIFIER, 'ldap' as SUBJECT_SOURCE_ID, CONCAT('ref:', role) as GROUP_NAME from HR_PEOPLE_ROLES");
loaderRunOneJob(group);
// loaderRunOneJob(group);

group = new GroupSave(gs).assignName("etc:deptLoader").assignCreateParentStemsIfNotExist(true).save();
group.getAttributeDelegate().assignAttribute(LoaderLdapUtils.grouperLoaderLdapAttributeDefName()).getAttributeAssign();
@@ -35,4 +34,4 @@ attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperL
attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectExpressionName(), '${subjectAttributes["subjectId"]}');
attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapGroupNameExpressionName(), 'ref:dept:${groupAttribute}');
attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapGroupDisplayNameExpressionName(), '${groupAttribute}');
loaderRunOneJob(group);
// loaderRunOneJob(group);
2 changes: 1 addition & 1 deletion ex401/ex401.1.end/Dockerfile
@@ -1,5 +1,5 @@
ARG VERSION_TAG
FROM tier/gte:401.1.6-$VERSION_TAG
FROM tier/gte:401.1.1-$VERSION_TAG

LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>" \
Vendor="TIER" \
91 changes: 67 additions & 24 deletions ex401/ex401.1.end/container_files/seed-data/bootstrap.gsh
@@ -1,6 +1,6 @@
gs = GrouperSession.startRootSession();
delStem("401.1.1")
addRootStem("401.4.end", "401.4.end")
addRootStem("401.1.end", "401.1.end")

// 401.1.1
addStem("test", "vpn", "vpn");
@@ -19,7 +19,12 @@ attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperL
attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectExpressionName(), "\${loaderLdapElUtils.convertDnToSpecificValue(subjectId)}");
loaderRunOneJob(group);

//Create the groups that do the grouper math to analyze the tables.
// stub out loader jobs
addGroup("ref", "faculty", "faculty");
addGroup("ref", "staff", "staff");
addGroup("ref", "student", "student");

// Create the groups that do the grouper math to analyze the tables.
addGroup("test:vpn", "vpn_faculty", "vpn_faculty");
addComposite("test:vpn:vpn_faculty", CompositeType.INTERSECTION, "test:vpn:vpn_legacy", "ref:faculty");
addGroup("test:vpn", "vpn_staff", "vpn_staff");
@@ -79,26 +84,64 @@ addMember("app:vpn:security:vpn_ajohnson409_mgr", "ajohnson409")
GrouperSession.start(findSubject("ajohnson409"))
addMember("app:vpn:service:ref:vpn_ajohnson409", "bsmith458")




addGroup("test", "cisoQuestionableVpnUsersList", "CISO VPN Questionable VPN List");
addMember("test:cisoQuestionableVpnUsersList","ahenderson36");
addMember("test:cisoQuestionableVpnUsersList","cpeterson37");
addMember("test:cisoQuestionableVpnUsersList","jclark39");
addMember("test:cisoQuestionableVpnUsersList","kbrown62");
addMember("test:cisoQuestionableVpnUsersList","tpeterson63");
addMember("test:cisoQuestionableVpnUsersList","pjohnson64");
addMember("test:cisoQuestionableVpnUsersList","aroberts95");
addMember("test:cisoQuestionableVpnUsersList","sdavis107");
addMember("test:cisoQuestionableVpnUsersList","mhenderson109");
addMember("test:cisoQuestionableVpnUsersList","jvales117");
addMember("test:cisoQuestionableVpnUsersList","sgrady139");
addMember("test:cisoQuestionableVpnUsersList","mprice142");
addMember("test:cisoQuestionableVpnUsersList","mwilliams144");
addMember("test:cisoQuestionableVpnUsersList","lpeterson153");
addMember("test:cisoQuestionableVpnUsersList","mvales154");

addGroup("test", "whyvpnaccess", "Why Do They Have VPN Access");
addComposite("test:whyvpnaccess", CompositeType.INTERSECTION, "app:vpn:vpn_authorized", "test:cisoQuestionableVpnUsersList");
// 401.1.5
// Attestation requirement
group = GroupFinder.findByName(gs, "app:vpn:service:ref:vpn_ajohnson409");
attribute = AttributeDefNameFinder.findByName("etc:attribute:attestation:attestation", true);
attributeAssignSave = new AttributeAssignSave(gs).assignPrintChangesToSystemOut(true);
attributeAssignSave.assignAttributeDefName(attribute);
attributeAssignSave.assignOwnerGroup(group);

attributeAssignOnAssignSave = new AttributeAssignSave(gs);
attributeAssignOnAssignSave.assignAttributeAssignType(AttributeAssignType.group_asgn);
attestationSendEmailAttributeDefName = AttributeDefNameFinder.findByName("etc:attribute:attestation:attestationSendEmail", false);
attributeAssignOnAssignSave.assignAttributeDefName(attestationSendEmailAttributeDefName);
attributeAssignOnAssignSave.addValue("true");
attributeAssignSave.addAttributeAssignOnThisAssignment(attributeAssignOnAssignSave);

attributeAssignOnAssignSave = new AttributeAssignSave(gs);
attributeAssignOnAssignSave.assignAttributeAssignType(AttributeAssignType.group_asgn);
attributeDefName = AttributeDefNameFinder.findByName("etc:attribute:attestation:attestationDirectAssignment", false);
attributeAssignOnAssignSave.assignAttributeDefName(attributeDefName);
attributeAssignOnAssignSave.addValue("true");
attributeAssignSave.addAttributeAssignOnThisAssignment(attributeAssignOnAssignSave);

attributeAssign = attributeAssignSave.save();

// Automatically expire vpn_consultant subject memberships in 180 days
numberOfDays = 180;
actAs = SubjectFinder.findRootSubject();
vpn_consultants = GroupFinder.findByName(gs, "app:vpn:service:ref:vpn_consultants");
attribAssign = vpn_consultants.getAttributeDelegate().addAttribute(RuleUtils.ruleAttributeDefName()).getAttributeAssign();
attribValueDelegate = attribAssign.getAttributeValueDelegate();
attribValueDelegate.assignValue(RuleUtils.ruleActAsSubjectSourceIdName(), actAs.getSourceId());
attribValueDelegate.assignValue(RuleUtils.ruleActAsSubjectIdName(), actAs.getId());
attribValueDelegate.assignValue(RuleUtils.ruleCheckTypeName(), RuleCheckType.membershipAdd.name());
attribValueDelegate.assignValue(RuleUtils.ruleThenEnumName(), RuleThenEnum.assignMembershipDisabledDaysForOwnerGroupId.name());
attribValueDelegate.assignValue(RuleUtils.ruleThenEnumArg0Name(), numberOfDays.toString());
attribValueDelegate.assignValue(RuleUtils.ruleThenEnumArg1Name(), "T");

addMember("app:vpn:service:ref:vpn_consultants", "jsmith")

// 401.1.4 VPN access audit for list of NetIDs
addGroup("test:vpn", "vpn_audit_list", "vpn_audit_list");
addMember("vpn_audit_list","ahenderson36");
addMember("vpn_audit_list","cpeterson37");
addMember("vpn_audit_list","jclark39");
addMember("vpn_audit_list","kbrown62");
addMember("vpn_audit_list","tpeterson63");
addMember("vpn_audit_list","pjohnson64");
addMember("vpn_audit_list","aroberts95");
addMember("vpn_audit_list","sdavis107");
addMember("vpn_audit_list","mhenderson109");
addMember("vpn_audit_list","jvales117");
addMember("vpn_audit_list","sgrady139");
addMember("vpn_audit_list","mprice142");
addMember("vpn_audit_list","mwilliams144");
addMember("vpn_audit_list","lpeterson153");
addMember("vpn_audit_list","mvales154");
addMember("vpn_audit_list","bsmith458");

addGroup("test:vpn", "vpn_audit", "vpn_audit");
addComposite("test:vpn:vpn_audit", CompositeType.INTERSECTION, "app:vpn:service:policy:vpn_authorized", "test:vpn:vpn_audit_list");

5 changes: 0 additions & 5 deletions ex401/manualBuild.sh
@@ -1,11 +1,6 @@
source ../buildVersion.sh
echo "Building gte:401 version ${VERSION_TAG}"
docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.1.1-${VERSION_TAG} ex401.1.1 \
&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.1.2-${VERSION_TAG} ex401.1.2 \
&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.1.3-${VERSION_TAG} ex401.1.3 \
&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.1.4-${VERSION_TAG} ex401.1.4 \
&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.1.5-${VERSION_TAG} ex401.1.5 \
&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.1.6-${VERSION_TAG} ex401.1.6 \
&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.1.end-${VERSION_TAG} ex401.1.end \
&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.2.1-${VERSION_TAG} ex401.2.1 \
&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.2.2-${VERSION_TAG} ex401.2.2 \

0 comments on commit 686644c

Please sign in to comment.