According to OpenFlow specification, OpenFlow switch can be connected to multiple controllers with different role.
I am now implementing mininet topology with OpenvSwitch. I would like to know how to specify the role of controllers to OpenvSwitch in Mininet?
The role is determined by the controller, please see the A 3.9. section in the Openflow 1.3 specification:
A.3.9 Role Request Message
When the controller wants to change its role, it uses the OFPT_ROLE_REQUEST message with the following structure:
OpenFlow Switch Specification Version 1.3.0
/* Role request and reply message. */
struct ofp_role_request {
struct ofp_header header; /* Type OFPT_ROLE_REQUEST/OFPT_ROLE_REPLY. */
uint32_t role; /* One of NX_ROLE_*. */
uint8_t pad[4]; /* Align to 64 bits. */
uint64_t generation_id; /* Master Election Generation Id */
};
OFP_ASSERT(sizeof(struct ofp_role_request) == 24);
The field role is the new role that the controller wants to assume, and can have the following values:
/* Controller roles. */
enum ofp_controller_role {
OFPCR_ROLE_NOCHANGE = 0, /* Don’t change current role. */
OFPCR_ROLE_EQUAL = 1, /* Default role, full access. */
OFPCR_ROLE_MASTER = 2, /* Full access, at most one master. */
OFPCR_ROLE_SLAVE = 3, /* Read-only access. */
};
If the role value is OFPCR_ROLE_MASTER, all other controllers which role was OFPCR_ROLE_MASTER are changed to OFPCR_ROLE_SLAVE. If the role value is OFPCR_ROLE_NOCHANGE, the current role of the controller is not changed ; this enable a controller to query its current role without changing it.
Upon receipt of a OFPT_ROLE_REQUEST message, the switch must return a OFPT_ROLE_REPLY message. The structure of this message is exactly the same as the OFPT_ROLE_REQUEST message, and the field role is the current role of the controller.
Additionally, if the role value in the message is OFPCR_ROLE_MASTER or OFPCR_ROLE_SLAVE, the switch must validate generation_id to check for stale messages. If the validation fails, the switch must discard the role request and return an error message with type OFPET_ROLE_REQUEST_FAILED and code OFPRRFC_STALE.
Related
I have RESTful APIs and in microservice architecture. Such as -
Auth service
User service
Product service
More ...
Currently, I am validating request via JWT token which can be obtained from Auth service. Now, time has come to implement an access control system.
It's an internal tool application (pretty complex) and my primary thought was to use RBAC (Role-based access control) but the application isn't traditional. In application, User A can pair up with another User B and once pair up completed, based on User B's settings User A can perform various action.
So permissions aren't static and they're based on other variables. So should I go for ABAC/PBAC system? Any suggestions?
Thoughts on ABAC
Subjects - Who is sending request e.g User A
Object - Accessing what? e.g Module A
Actions - Read or write? e.g Read GET request
Environment - condition e.g for which User? (User B)
My biased answer is: yes you should :-) (I work for Axiomatics and all we do is PBAC/ABAC and have done so for 15 years).
Note that PBAC and ABAC in this context are the same. PBAC is actually a much older concept. We've been using policies in many places e.g. network access control or SDDL in the past.
The main benefit of attribute-based access control for you (abac) is that it will give you the freedom to adapt your access control policies over time without having to rewrite your application. Effectively, you decouple / externalize authorization from the application.
The following shows the basic architectural flow in ABAC whereby a component (the PEP) intercepts the business flow and converts it into an authorization flow (Can Alice view record 123?).
Policies can be written in xacml or alfa. I prefer the latter since its syntax is super lightweight (read more on Wikipedia).
For instance you could write:
namespace com.acme{
/**
* Tutorial 101 - a flat approach using 4 rules
*/
policyset recordsAccess{
apply firstApplicable
/**
* Records access control
*/
policy records{
target clause object.objectType == "record"
apply firstApplicable
/**
* R1 - A manager can view any records
*/
rule managersView{
target clause user.role == "manager" and action.actionId == "view"
permit
}
/**
* R2 - An employee can view a record in their own department
*/
rule employeesView{
target clause user.role == "employee" and action.actionId == "view"
condition user.department == record.department
permit
}
/**
* R3 - An employee can edit a record they own, if it is in draft mode
*/
rule employeeEdit{
target clause user.role == "employee" and action.actionId == "edit" and record.status == "draft"
condition com.acme.record.owner == com.acme.user.employeeId
permit
}
/**
* R4 - A manager can publish a record if the record is in final
* mode and it belongs to a employee below that manager.
*/
rule managerPublish{
target clause user.role == "manager" and action.actionId == "publish"
condition stringIsIn(stringOneAndOnly(com.acme.record.owner),com.acme.user.subordinate)
permit
}
}
}
}
I currently have a setup using WebRTC -> Asterisk where I can call and send messages. When I make a call from A -> B all of B's registered devices get called (so if he is logged in several times).
However using MessageSend the SIP message is only delivered to one registered, not all. How can I make it send to all registered devices?
Is it possible, if not is there any other way it can be done inside of Asterisk?
(Using Asterisk 15.5).
Thanks!
Asterisk (at least when using PJSIP) and a given endpoint strips any URI details and will only use the endpoint and does not loop over all registered contacts.
From messge.c 'msg_send_exec'
Gets the outbound from res_pjsip_messaging.c 'get_outbound_endpoint'
/* attempt to extract the endpoint name */
if ((aor_uri = strchr(name, '/'))) {
/* format was 'endpoint/(aor_name | uri)' */
*aor_uri++ = '\0';
} else if ((aor_uri = strchr(name, '#'))) {
/* format was 'endpoint#domain' - discard the domain */
*aor_uri = '\0';
/*
* We may want to match without any user options getting
* in the way.
*/
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(name);
}
/* at this point, if name is not empty then it
might be an endpoint, so try to retrieve it */
if (ast_strlen_zero(name)
|| !(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
name))) {
/* an endpoint was not found, so assume sending directly
to a uri and use the default outbound endpoint */
*uri = ast_strdup(to);
return ast_sip_default_outbound_endpoint();
}
From what I understant if you only use a URI (like pjsip:123.12.123.12:1234) it will just look for the default endpoint which will always be the same.
The documentation for Spring WebSockets states:
4.4.13. User Destinations
An application can send messages targeting a specific user, and Spring’s STOMP support recognizes destinations prefixed with "/user/" for this purpose. For example, a client might subscribe to the destination "/user/queue/position-updates". This destination will be handled by the UserDestinationMessageHandler and transformed into a destination unique to the user session, e.g. "/queue/position-updates-user123". This provides the convenience of subscribing to a generically named destination while at the same time ensuring no collisions with other users subscribing to the same destination so that each user can receive unique stock position updates.
Is this supposed to work in a multi-server environment with RabbitMQ as broker?
As far as I can tell, the queue name for a user is generated by appending the simpSessionId. When using the recommended client library stomp.js this results in the first user getting the queue name "/queue/position-updates-user0", the next gets "/queue/position-updates-user1" and so on.
This in turn means the first users to connect to different servers will subscribe to the same queue ("/queue/position-updates-user0").
The only reference to this I can find in the documentation is this:
In a multi-application server scenario a user destination may remain unresolved because the user is connected to a different server. In such cases you can configure a destination to broadcast unresolved messages to so that other servers have a chance to try. This can be done through the userDestinationBroadcast property of the MessageBrokerRegistry in Java config and the user-destination-broadcast attribute of the message-broker element in XML.
But this only makes the it possible to communicate with a user from a different server than the one where the web socket is established.
I feel I'm missing something? Is there anyway to configure Spring to be able to safely use MessagingTemplate.convertAndSendToUser(principal.getName(), destination, payload) in a multi-server environment?
If they need to be authenticated (I assume their credentials are stored in a database) you can always use their database unique user id to subscribe to.
What I do is when a user logs in they are automatically subscribed to two topics an account|system topic for system wide broadcasts and account|<userId> topic for specific broadcasts.
You could try something like notification|<userid> for each person to subscribe to then send messages to that topic and they will receive it.
Since user Ids are unique to each user you shouldn't have an issue within a clustered environment as long as each environment is hitting the same database information.
Here is my send method:
public static boolean send(Object msg, String topic) {
try {
String destination = topic;
String payload = toJson(msg); //jsonfiy the message
Message<byte[]> message = MessageBuilder.withPayload(payload.getBytes("UTF-8")).build();
template.send(destination, message);
return true;
} catch (Exception ex) {
logger.error(CommService.class.getName(), ex);
return false;
}
}
My destinations are preformatted so if i want to send a message to user with id of one the destinations looks something like /topic/account|1.
Ive created a ping pong controller that tests websockets for users who connect to see if their environment allows for websockets. I don't know if this will help you but this does work in my clustered environment.
/**
* Play ping pong between the client and server to see if web sockets work
* #param input the ping pong input
* #return the return data to check for connectivity
* #throws Exception exception
*/
#MessageMapping("/ping")
#SendToUser(value="/queue/pong", broadcast=false) // send only to the session that sent the request
public PingPong ping(PingPong input) throws Exception {
int receivedBytes = input.getData().length;
int pullBytes = input.getPull();
PingPong response = input;
if (pullBytes == 0) {
response.setData(new byte[0]);
} else if (pullBytes != receivedBytes) {
// create random byte array
byte[] data = randomService.nextBytes(pullBytes);
response.setData(data);
}
return response;
}
I have been trying to setup gerrit to work with LDAP authentication. I read documentation numerous time some link do not work to the examples documentation pulled from tuleap on subject comes up with different solutions and explanations I have found three different configurations for ldap.inc from tuleap this is very confusing lacking explanation too.
So i am stuck with this problem. I have spent hours reading and trying to sort this out. Can someone tell me what am I doing wrong? here is my
ldap.inc
<?php
// LDAP server(s) to query for more information on Tuleap users and
// for authentication.
// You may use a comma-separated list if there are several servers available
// (leave blank to disable LDAP lookup).
// To specify secure LDAP servers, use 'ldaps://servername'
$sys_ldap_server = 'techhub.lt';
// To enable LDAP information on Tuleap users, also define the DN
// (distinguised name) to use in LDAP queries.
// The ldap filter is the filter to use to query the LDAP directory
// (%name% are substituted with the value from the user table)
$sys_ldap_dn = 'dc=techhub,dc=lt';
// For LDAP systems that do not accept anonymous binding, define here
// a valid DN and password:
$sys_ldap_bind_dn = "cn=admin,dc=techhub,dc=lt";
$sys_ldap_bind_passwd = "pass";
// LDAP authentication:
// Tuleap only supports authentication with a attempt to bind with LDAP server
// with a DN and a password.
// As the DN is usually long (eduid=1234,ou=people,dc=tuleap,dc=com) people
// usually authenticate themself with a login. So we need to first look
// for the DN that correspond to the given login and once found attempt to bind
// with the given password.
// In order to autenticate successfully users you need to properly
// User login (authentication 1st step)
$sys_ldap_uid = 'uid';
// User unique identifier. It's probably not the uid (or login) because it
// may change. This is a value that never change whatever happens to the
// user (even after deletion). It correspond to ldap_id field in user table
// in database.
// (authentication 2st step)
$sys_ldap_eduid = 'eduid';
// User common name
$sys_ldap_cn = 'cn';
// User email address
$sys_ldap_mail = 'mail';
// Specific DN to look for people
// You may use more than one DN separated by ; if you want to use several branches.
// Example : 'ou=People, dc=st, dc=com ; ou=Extranet, dc=st, dc=com'
$sys_ldap_people_dn = 'ou=people,dc=techhub,dc=lt';
// Filter used to look for user. It should cover a wide selection of
// fields because it's aim to find a user whatever it's given (email, name,
// login, etc).
$sys_ldap_search_user='(|(uid=%words%)(cn=%words%)(mail=%words%))';
// By default tooltip search is using ($sys_ldap_cn=%words%*) search filter (Hardcoded)
// You can change for a more sophisticated search
// $sys_ldap_tooltip_search_user='(&(|(sn=%words%*)(givenName=%words%*)(uid=%words%*))(!(givenName=BoiteVocale))(uid=*))';
// By default tooltip search attrs are $sys_ldap_cn and $sys_ldap_uid (Hardcoded)
// You can choose the attributes the search will retrieve
// $sys_ldap_tooltip_search_attrs='uid;sn;givenName';
// On account creation, what it the default user status (A, R, ...)
$sys_ldap_default_user_status = 'A';
// Enable LDAP based authentication for SVN by default for new projects
$sys_ldap_svn_auth = 1;
// Enable LDAP daily synchronization
$sys_ldap_daily_sync = 1;
// Enable usage of LDAP for people management. For instance autocompletion on
// user list, automatic creation of users not already referenced in the forge.
$sys_ldap_user_management = 1;
// Enable ldap group management.
// This allows to mirror a LDAP group defined in LDAP directory within the forge
// Doesn't work yet with only works with OpenLDAP compatible directories yet.
$sys_ldap_grp_enabled = 1;
// Specific DN where the user groups are
$sys_ldap_grp_dn = 'ou=groups,dc=techhub,dc=lt';
// Field that reprsent group name
$sys_ldap_grp_cn = 'cn';
// Field that indicate the membership of a user in a group
$sys_ldap_grp_member = 'uniquemember';
?>
AND gerrit.conf
[gerrit]
basePath = git
canonicalWebUrl = http://techhub.lt:2401/
[database]
type = H2
database = db/ReviewDB
[sendemail]
smtpServer = localhost
[container]
user = root
javaHome = /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.45.x86_64/jre
[sshd]
listenAddress = *:29418
[httpd]
listenUrl = http://*:2401/
[cache]
directory = cache
[auth]
type = LDAP
[ldap]
server = ldap://techhub.lt
accountBase = ou=people,dc=cro,dc=techhub,dc=lt
groupBase = ou=group,dc=cro,dc=techhub,dc=lt
accountFullName = cn
That's 2 different problems.
Do you manage to authenticate with LDAP accounts on gerrit ?
If yes, I think the problem comes from "$sys_ldap_eduid = 'eduid';" parameter in tuleap ldap config. This attribute should be the unique identifier of one's account in ldap (either you have such an attribute of you can use 'uid' as a fallback.
My application is an MVC4 application with a Domain Model created in EF 5 Code First. The application requires Authentication / Authorization, and I want to use the default ASP.NET Membership Provider.
With this in mind, I have gone ahead and used the aspnet_reqsql utility to add all the tables necessary for the ASP.NET Default Membership provider.
However, my application needs to store more information about the User than what is provided by default by the Membership provider. For example:
First Name
Last Name
Date of Birth
Address (split into different
columns)
These things are not present in the membership provider tables. So I went ahead and added all the missing columns to the users table, and also created an Addresses table, and created a relationship between the User and the Address.
I then went into my Registration View Model, and added the missing data fields, I then went into the AccountController and checked the method that gets called to register a user. It is this:
//
// Summary:
// Creates a new user profile entry and a new membership account.
//
// Parameters:
// userName:
// The user name.
//
// password:
// The password for the user.
//
// propertyValues:
// (Optional) A dictionary that contains additional user attributes. The default
// is null.
//
// requireConfirmationToken:
// (Optional) true to specify that the user account must be confirmed; otherwise,
// false. The default is false.
//
// Returns:
// A token that can be sent to the user to confirm the user account.
//
// Exceptions:
// System.InvalidOperationException:
// The WebMatrix.WebData.SimpleMembershipProvider.Initialize(System.String,System.Collections.Specialized.NameValueCollection)
// method was not called.-or-The Overload:WebMatrix.WebData.WebSecurity.InitializeDatabaseConnection
// method was not called.-or-The WebMatrix.WebData.SimpleMembershipProvider
// membership provider is not registered in the configuration of your site.
// For more information, contact your site's system administrator.
public static string CreateUserAndAccount(string userName, string password, object propertyValues = null, bool requireConfirmationToken = false);
This method is confusing me a lot ! I was expecting to see the logic of data insertion into the database, so that I may edit it and add make the method take care of my newly added fields too, but all that missing!
What am I missing? How can I achieve the type of registration that I want?
First of all, you want to use new ASP.NET Universal Providers which uses Entity Framework.
If you want to add custom columns, create a new table like the following, and retrieves that custom data based on UserId by yourself.
Note: You cannot alter (add/remove) columns of any table created by Membership Provider, if you want to use DefaultMembershipProvider.
In other words, if you start adding columns, you'll have to implement CustomMembersipProvider. I do not recommend it if you are new to MembershipProvider.